Как исправить «ошибку сегментации» в этом случае - PullRequest
0 голосов
/ 26 марта 2019

Я хочу сделать программу, которая читает строку с информацией о партии, разделяет информацию между "/" и затем создает объект с информацией.

Я сделал цикл, как показано в Интернете. Если я просто хочу напечатать его, он работает нормально, но когда я пытаюсь присвоить его переменным, происходит ошибка - Ошибка сегментации

Моя структура выглядит следующим образом:

typedef struct {
  char description[40];
  int date;
  int time;
  int duration;
  int room;
  char parent[40];
  char kids[3][40]
} Party;

И функция, которая читает строку:

void createParty():
  Party p;
  char s[LIMIT] = "John's Birthday/25032019/2230/10/1/Thomas/Anna/Jack/Sarah";
  char c[2] = "c";
  char *token;
  int i=0;

  token = strtok(str, s);

   while( token != NULL ) {
      printf( " %s\n", token );
      token = strtok(NULL, s);

      if (i==0)
        strcpy(p.description,token);
      else if (i==1)
        p.date=atoi(token);
      else if (i==2)
        p.time=atoi(token);
      else if (i==3)
        p.duration=atoi(token):
      else if (i==4)
        p.room=atoi(token);
      else if (i==5)
        strcpy(p.parent,token);
      else
        strcpy(p.kids[j-6],token);

      i++
   }

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

Спасибо!

1 Ответ

0 голосов
/ 26 марта 2019

следующий предложенный код:

  1. исключает многократное тестирование переменной i
  2. исключает использование «магических» чисел
  3. исправляет логические ошибки
  4. исправляет синтаксические ошибки
  5. гарантирует, что массивы символов не переполняются
  6. чисто компилирует
  7. нужна функция 'main () function to call the createParty () `
  8. правильно прототипирует функцию: createParty()
  9. гибко определяет структуру
  10. определяет имя тега, чтобы отладчик мог зацикливаться на отдельных полях в структуре
  11. отделяет 'typedef' от определения структуры
  12. позволяет иметь более одной стороны, просто изменив MAX_PARTIES на значение, отличное от 1
  13. Документы, почему каждый заголовочный файл был включен
  14. использует соответствующий горизонтальный и вертикальный интервал для удобства чтения
  15. код OP, называемый strtok() в верхней части цикла, поэтому результаты первого вызова strtok() были напечатаны, но никогда не обрабатывались в структуре

и теперь предложенный код:

#include <stdio.h>    // printf()
#include <string.h>   // strtok(), strncpy()
#include <stdlib.h>   // atoi()

#define LIMIT          500
#define MAX_PARTIES    1
#define MAX_DESC_LEN   40
#define MAX_PARENT_LEN 40
#define MAX_KIDS       3
#define MAX_KID_LEN    40

struct PARTY
{
  char description[ MAX_DESC_LEN ];
  int date;
  int time;
  int duration;
  int room;
  char parent[ MAX_PARENT_LEN ];
  char kids[ MAX_KIDS ][ MAX_KID_LEN ];  // was missing trailing semicolon 
};
typedef struct PARTY MyParty;

// prototypes
void createParty( void );    //  notice 'void' parameter in prototype


void createParty()           //  removed extranious trailing char
{
    MyParty p[ MAX_PARTIES ]; // Note: a 2 space indent level can be 'lost' with variable width fonts
    char s[LIMIT] = "John's Birthday/25032019/2230/10/1/Thomas/Anna/Jack/Sarah";
    char delimiters[] = "//";  // note using '//' as first slash 'escapes' the second slash
    int i=0;

    char * token = strtok( s, delimiters );

    while( token  && i < 11 ) 
    {
        printf( "%s\n", token );

        switch( i )
        {
            case 0:
                strncpy( p[i].description, token, MAX_DESC_LEN-1 );
                break;

            case 1:
                p[i].date = atoi( token );
                break;

            case 2:
                p[i].time = atoi( token );
                break;

            case 3:
                p[i].date = atoi( token );
                break;

            case 4:
                p[i].duration = atoi( token );
                break;

            case 6:
                p[i].room = atoi( token );
                break;

            case 7:
                strncpy( p[i].parent, token, MAX_PARENT_LEN-1 );
                break;

            case 8:
                strncpy( p[i].kids[0], token, MAX_KID_LEN-1 );
                break;

            case 9:
                strncpy( p[i].kids[1], token, MAX_KID_LEN-1 );
                break;

            case 10:
                strncpy( p[i].kids[2], token, MAX_KID_LEN-1 );
                break;

            default:
                printf( "unexpected field found: %s\n", token );
                break;
        }

        i++;  // was missing trailing semicolon
        token = strtok( NULL, delimiters );  // prep for next loop iteration
    } // end switch
}  // end function: createParty()
...