问题
I am making a code to parse some input data and write it to a file in a special formatting. I am removing a newline from each string token as so:
token[strlen(token)-2] ='\0'
It is -2
because the last element is \0
. This much works. However, the final element of the input data does NOT have a newline, so using just that ends up removing the second-to-last character from the last input set.
original input: 0.38
after running it through the removal: 0.3
The obvious solution is to check if the newline is there before removing. I do this:
if(token[strlen(token)-2] =='\n') token[strlen(token)-2] ='\0';
However, after adding the if clause, the newline is no longer removed! What am i doing wrong? Snippit from the whole code:
while((token = strsep(&line, ",")) != NULL){
if(x++ == 1){
fwrite(" <item>\n", 11, 1, fw);
fwrite(" <name>", 14, 1, fw);
fwrite(token, strlen(token), 1, fw);
fwrite("</name>\n", 8, 1, fw);
}
else if(isdigit(token[0])) {
if(token[strlen(token)-2] =='\n') token[strlen(token)-2] ='\0';
fwrite(" <SPC>", 13, 1, fw);
fwrite(token, strlen(token), 1, fw);
fwrite("</SPC>\n", 7, 1, fw);
fwrite(" </item>\n", 12, 1, fw);
}
}
回答1:
Your newline should be at line[strlen(line)-1]
, but you may work under Windows where a newline actually consists of a carriage return followed by a newline. This would explain why line[strlen(line)-2]='\0'
is successful in removing the end-of-line, but the test fails.
回答2:
I think your problem is using -2
instead of -1
, use this function to remove whitespace from the right side of the string:
#include <ctype.h>
/* 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;
}
回答3:
For the sake of flexibility (no character counting, no character literals) I'd do:
#include <string.h>
...
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");
This solution covers *IX, ms and mac line ends, and also would survive things like:
#define char wchar_t
回答4:
size_t len;
for(len=strlen(token); len && (token[len-1] == '\r' || token[len-1] == '\n'); len--) {
token[len] = 0;
}
or, you could use strcspn():
size_t len;
len = strcspn(token, "\r\n" );
token[len] = 0;
Or, as a one-liner:
token [ token + strcspn(token, "\r\n" )] = 0;
Do note that the first fragment only removes the trailing '\r's and '\n's; the srcspn() fragments remove everything from the first '\r' or '\n' they encounter.
来源:https://stackoverflow.com/questions/16000569/newline-removal-not-working-after-trying-to-verify-it-exists