6

so I have an input file with a bunch of names and numbers. I started using strtok to break up the string so that I can extract all the data out of each string. Everything seems to be working correctly, but for some reason it's not discarding the newline character.

int procFile(PERSON **data, FILE* fpFile)
{
//  Local Declaration
char temp[1000];
char proc[15];
char *entry;
char *loc;
int success = 0;

//  Statement
if(fgets(temp, sizeof(temp), fpFile))
{
    (*data) = aloMem(); // free
    entry = temp;
    loc = strtok(entry, " ()-");
    strcpy(proc, loc);
    loc = strtok(NULL, " ()-");
    strcat(proc, loc);
    loc = strtok(NULL, " ()-");
    strcat(proc, loc);
    sscanf(proc, "%ld", &(*data)->phone);
    loc = strtok(NULL, "\0");
    strcpy((*data)->name, loc);
    success++;
    printf("%s1", (*data)->name);
}

return success;
}// procFile

I tried printing the results to see if it's working correctly and this is my output.

Brown, Joanne
1South, Frankie
1Lee, Marie
1Brown, Joanne
1Trapp, Ada Eve
1Trapp, David
1White, D. Robert
1Lee, Victoria
1Marcus, Johnathan
1Walljasper, Bryan
1Trapp, Ada Eve
1Brown, Joanne
1Andrews, Daniel

It's printing the 1 after each name on a newline, rather than right after the name. Can someone explain to me how I can fix the problem?

Theodoros Chatzigiannakis
  • 28,773
  • 8
  • 68
  • 104
Nathan
  • 483
  • 4
  • 7
  • 19
  • 2
    Removing trailing whitespaces can most portable be done using `strpbrk()`: http://stackoverflow.com/a/16000784/694576 – alk May 22 '13 at 06:23

3 Answers3

6

Add \r \n and perhaps \t to your list of delimiters in strtok

AlexK
  • 1,279
  • 8
  • 19
5

Before tokenizing temp, get rid of the newline as follows:

char *newline = strchr( temp, '\n' );
if ( newline )
  *newline = 0;

strchr searches temp for the newline character, and returns a pointer to it (or NULL if the newline character isn't found). We then overwrite the newline with a 0 (string terminator).

John Bode
  • 119,563
  • 19
  • 122
  • 198
  • 7
    Or add `\n` to the list of delimiters; no need for a separate scan of the input line then. – Jonathan Leffler May 21 '13 at 19:41
  • @John Bode:That's a performance hit. You will be scanning the string twice, once for the \n and again for the tokens. While it is perfectly normal for Java and C# programmers to do that, we C++ coders know better :) – AlexK May 21 '13 at 19:43
  • There may be a \r there as well, as in CR LF – AlexK May 21 '13 at 19:48
  • @JonathanLeffler: Or, that too. – John Bode May 21 '13 at 21:21
  • 1
    @AlexK: Given that this code is I/O bound, I'm not too worried about an extra scan. – John Bode May 21 '13 at 21:21
  • @John Bode: Well if we are not worried about the overhead, lets add two more, one for \r and another one for \t. And this list of exceptions seems to have a tendency to grow... – AlexK May 23 '13 at 18:08
  • @AlexK Before you get sarcastic, you should try out your suggestion. Escaped characters are not recognized in the delimiter string by strtok. – yamex5 May 29 '23 at 21:45
4

According to man fgets:

fgets() reads in at most one less than size characters from stream and stores them into the buffer pointed to by s. Reading stops after an EOF or a newline. If a newline is read, it is stored into the buffer.

That's where you are getting your newlines from.

alk
  • 69,737
  • 10
  • 105
  • 255
AlexK
  • 1,279
  • 8
  • 19