0xFF
0xFF

Reputation: 4178

Can printf change its parameters?

EDIT: complete code with main is here http://codepad.org/79aLzj2H

and once again this is were the weird behavious is happening

for (i = 0; i<tab_size; i++)
{
  //CORRECT OUTPUT
  printf("%s\n", tableau[i].capitale);
  printf("%s\n", tableau[i].pays);
  printf("%s\n", tableau[i].commentaire);
  //WRONG OUTPUT
  //printf("%s --- %s --- %s |\n", tableau[i].capitale, tableau[i].pays, tableau[i].commentaire);
}


I have an array of the following strcuture

struct T_info
{
    char capitale[255];
    char pays[255];
    char commentaire[255];
};

struct T_info *tableau;

This is how the array is populated

int advance(FILE *f)
{
  char c;

  c = getc(f);
  if(c == '\n')
    return 0;

  while(c != EOF && (c == ' ' || c == '\t'))
  {
    c = getc(f);
  }

  return fseek(f, -1, SEEK_CUR);

}

int get_word(FILE *f, char * buffer)
{
  char c;
  int count = 0;
  int space = 0;

  while((c = getc(f)) != EOF)
    {
      if (c == '\n')
      {
    buffer[count] = '\0';
    return -2;
      }

      if ((c == ' ' || c == '\t') && space < 1)
      {
    buffer[count] = c;
    count ++;
    space++;
      }
      else
      {
    if (c != ' ' && c != '\t')
    {
      buffer[count] = c;
      count ++;
      space = 0;
    }       
    else /* more than one space*/
    {
     advance(f);
     break;
    }
      }
    }

   buffer[count] = '\0';
   if(c == EOF)
     return -1;

   return count;
}

void fill_table(FILE *f,struct T_info *tab)
{
    int line = 0, column = 0;

    fseek(f, 0, SEEK_SET);

    char buffer[MAX_LINE];
    char c;
    int res;

    int i = 0;
    while((res = get_word(f, buffer)) != -999)
    {
      switch(column)
      {
        case 0:
        strcpy(tab[line].capitale, buffer); 
        column++;
          break;
        case 1:
          strcpy(tab[line].pays, buffer);
          column++;
          break;
        default:
          strcpy(tab[line].commentaire, buffer);    
          column++;
          break;
      }
      /*if I printf each one alone here, everything works ok*/
          //last word in line
      if (res == -2)
      {
        if (column == 2)
        {
          strcpy(tab[line].commentaire, " ");       
        }
//wrong output here
        printf("%s -- %s -- %s\n", tab[line].capitale, tab[line].pays, tab[line].commentaire);

        column = 0;
          line++;
          continue;
      }
      column = column % 3;

      if (column == 0)
      {
        line++;
      }

      /*EOF reached*/
      if(res == -1)
        return;

    }
    return ;
}

Edit :

trying this

    printf("%s -- ", tab[line].capitale);
    printf("%s --", tab[line].pays);
    printf("%s --\n", tab[line].commentaire);

gives me as result

 --  --abi  -- Emirats arabes unis

I expect to get

Abu Dhabi -- Emirats arabes unis --

Am I missing something?

Upvotes: 2

Views: 1323

Answers (4)

Mike McNertney
Mike McNertney

Reputation: 527

It's highly unlikely that printf is your problem. What is far, far more likely is that you're corrupting memory and your strange results from printf are just a symptom.

There are several places I see in your code which might result in reading or writing past the end of an array. It's hard to say which of them might be causing you problems without seeing your input, but here are a few that I noticed:

  1. get_lines_count won't count the last line if it doesn't end in a newline, but your other methods will process that line
  2. advance will skip over a newline if it is preceded by spaces, which will cause your column-based processing to get off, and could result in some of your strings being uninitialized
  3. get_word doesn't do any bounds checks on buffer

There may be others, those were just the ones that popped out at me.

Upvotes: 1

TheCodeArtist
TheCodeArtist

Reputation: 22487

From your comments, i am assuming if you use these printf statements,

  printf("%s\n", tableau[i].capitale);
  printf("%s", tableau[i].pays);
  printf("%s\n", tableau[i].commentaire);

then everything works fine...

So try replacing your single printf statement with this. (Line no. 173 in http://codepad.org/79aLzj2H)

  printf("%s\n %s %s /n", tableau[i].capitale, tableau[i].pays, tableau[i].commentaire);

Upvotes: 0

Juliano
Juliano

Reputation: 41387

I tested your code, adding the missing parts (MAX_LINE constant, main function and a sample datafile with three columns separated by 2+ whitespace), and the code works as expected.

Perhaps the code you posted is still not complete (fill_table() looks for a -999 magic number from get_word(), but get_word() never returns that), your main function is missing, so we don't know if you are properly allocating memory, etc.

Unrelated but important: it is not recommended (and also not portable) to do relative movements with fseek in text files. You probably want to use ungetc instead in this case. If you really want to move the file pointer while reading a text stream, you should use fgetpos and fsetpos.

Your approach for getting help is very wrong. You assumed that printf had side effects without even understanding your code. The problem is clearly not in printf, but you held information unnecessarily. Your code is not complete. You should create a reduced testcase that compiles and displays your problem clearly, and include it in full in your question. Don't blame random library functions if you don't understand what is really wrong with your program. The problem can be anywhere.

Upvotes: 0

sepp2k
sepp2k

Reputation: 370132

Does printf have side effects?

Well, it prints to the screen. That's a side effect. Other than that: no.

is printf changing its parameters

No

I get wrong resutts [...] what is going on?

If by wrong results you mean that the output does not appear when it should, this is probably just a line buffering issue (your second version does not print newline which may cause the output to not be flushed).

Upvotes: 5

Related Questions