Может printf изменить свои параметры? - PullRequest
2 голосов
/ 18 апреля 2010

EDIT: полный код с основным здесь http://codepad.org/79aLzj2H

и опять это странное поведение

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);
}


У меня есть массив следующей строки

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

struct T_info *tableau;

Так заполняется массив

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 ;
}

Редактировать:

пытается это

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

дает мне как результат

 --  --abi  -- Emirats arabes unis

Я ожидаю получить

Abu Dhabi -- Emirats arabes unis --

Я что-то упустил?

Ответы [ 4 ]

5 голосов
/ 18 апреля 2010

Есть ли у printf побочные эффекты?

Ну, это печатает на экран. Это побочный эффект. Кроме этого: нет.

printf изменяет свои параметры

нет

Нет

Я получаю неправильные результаты [...] что происходит?

Если из-за неправильных результатов вы имеете в виду, что вывод не появляется, когда должен, это, вероятно, просто проблема буферизации строки (ваша вторая версия не печатает перевод строки, что может привести к тому, что вывод не будет сброшен).

1 голос
/ 18 апреля 2010

Маловероятно, что printf - ваша проблема. Что гораздо, гораздо более вероятно, что вы повреждаете память, и ваши странные результаты от printf являются лишь симптомом.

В вашем коде есть несколько мест, которые могут привести к чтению или записи после конца массива. Трудно сказать, какие из них могут вызывать у вас проблемы, не видя вашего вклада, но вот некоторые из них, которые я заметил:

  1. get_lines_count не будет считать последнюю строку, если она не заканчивается новой строкой, но другие методы будут обрабатывать эту строку
  2. advance пропустит символ новой строки, если ему предшествуют пробелы, что приведет к сбою обработки на основе столбцов и может привести к неинициализации некоторых строк
  3. get_word не выполняет никаких проверок границ для buffer

Могут быть и другие, именно те, которые выскакивали на меня.

0 голосов
/ 18 апреля 2010

Исходя из ваших комментариев, я предполагаю, что если вы используете эти операторы printf,

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

тогда все отлично работает ...

Так что попробуйте заменить ваш единственный оператор printf этим. ( Строка № 173 in http://codepad.org/79aLzj2H)

  printf("%s\n %s %s /n", tableau[i].capitale, tableau[i].pays, tableau[i].commentaire);
0 голосов
/ 18 апреля 2010

Я протестировал ваш код, добавив недостающие части (константу MAX_LINE, основную функцию и образец файла данных с тремя столбцами, разделенными пробелом 2+), и код работает, как и ожидалось.

Возможно, опубликованный вами код все еще не завершен (fill_table () ищет магическое число -999 в get_word (), но get_word () никогда не возвращает его), ваша основная функция отсутствует, поэтому мы не знаем, Вы правильно распределяете память и т. д.

Не связано, но важно: не рекомендуется (и также не переносимо) делать относительные перемещения с fseek в текстовых файлах. В этом случае вы, вероятно, захотите использовать ungetc. Если вы действительно хотите переместить указатель файла во время чтения текстового потока, вы должны использовать fgetpos и fsetpos.

Ваш подход к получению помощи очень неправильный. Вы предполагали, что у printf есть побочные эффекты, даже не понимая ваш код. Проблема явно не в printf, но вы держали информацию без необходимости. Ваш код не завершен. Вам следует создать сокращенный тестовый сценарий, который четко компилирует и отображает вашу проблему, и полностью включите ее в свой вопрос. Не вините случайные библиотечные функции, если вы не понимаете, что на самом деле не так с вашей программой. Проблема может быть где угодно.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...