Удаление новой строки не работает после попытки ее проверки

Я делаю код для анализа некоторых входных данных и записи его в файл в специальном форматировании. Я удаляю новую строку из каждого токена так:

token[strlen(token)-2] ='\0' 

Это -2 потому что последний элемент равен \0 . Это много работает. Тем не менее, последний элемент входных данных НЕ имеет новую линию, поэтому использование только этого заканчивается удалением второго-последнего символа из последнего набора входных данных.

 original input: 0.38 after running it through the removal: 0.3 

Очевидным решением является проверка наличия новой строки перед удалением. Я сделаю это:

 if(token[strlen(token)-2] =='\n') token[strlen(token)-2] ='\0'; 

Однако после добавления предложения if новая строка больше не удаляется! Что я делаю неправильно? Snippit из всего кода:

  while((token = strsep(&line, ",")) != NULL){ if(x++ == 1){ fwrite(" \n", 11, 1, fw); fwrite(" ", 14, 1, fw); fwrite(token, strlen(token), 1, fw); fwrite("\n", 8, 1, fw); } else if(isdigit(token[0])) { if(token[strlen(token)-2] =='\n') token[strlen(token)-2] ='\0'; fwrite(" ", 13, 1, fw); fwrite(token, strlen(token), 1, fw); fwrite("\n", 7, 1, fw); fwrite(" \n", 12, 1, fw); } } 

Ваша line[strlen(line)-1] новой строки должна быть в line[strlen(line)-1] , но вы можете работать в Windows, где line[strlen(line)-1] фактически состоит из возврата каретки, за которым следует новая строка. Это объясняет, почему line[strlen(line)-2]='\0' успешна при удалении конца строки, но тест терпит неудачу.

Я думаю, что ваша проблема заключается в использовании -2 вместо -1 , используйте эту функцию для удаления пробелов с правой стороны строки:

 #include  /* remove whitespace from the right */ void rtrim(char *s) { char *p; for (p = s + strlen(s) - 1; p >= s && isspace(p[0]); p--); p[1] = 0; } 

Ради гибкости (без символьного подсчета, без символов) я бы сделал:

 #include  ... char * rtrim(char * str, const char * del) { if (str) { char * pc; while (pc = strpbrk(str, del)) { *pc = 0; } } return str; } ... char * line; ... /* let line point to some string */ /* to remove any kind of line end, call it like this: */ line = rtrim(line, "\n\r"); 

Это решение охватывает концы * IX, ms и mac, а также выдержат такие вещи, как:

 #define char wchar_t 
 size_t len; for(len=strlen(token); len && (token[len-1] == '\r' || token[len-1] == '\n'); len--) { token[len] = 0; } 

или, вы можете использовать strcspn ():

 size_t len; len = strcspn(token, "\r\n" ); token[len] = 0; 

Или, как однострочный:

 token [ token + strcspn(token, "\r\n" )] = 0; 

Обратите внимание, что первый fragment удаляет только конечные «\ r и» \ n; fragmentы srcspn () удаляют все из первых «\ r» или «\ n», с которыми они сталкиваются.