2014-04-25 1 views
0

EDIT: J'ai développé une solution qui fonctionne:strncpy() erreur de segmentation (encore une fois) [résolu auto-]

writeLine[0] = '\0'; 

    while(fgets(readBuffer, sizeof(readBuffer), openFile) != NULL) 
    { 
     if (readBuffer[0] != EOF) 
     {    
      for(word = readBuffer; NULL != (word = strtok(word, " \t\n")); word=NULL) 
      { 
       printf("%s\n", writeLine); 
       if(strlen(word) + strlen(writeLine) < numChars) 
       { 
        strcat(writeLine, word); 
        strcat(writeLine, " "); 
       } 
       else 
       { 
        printf("%s", "print\n"); 
        fprintf(writeFile, "%s\n", writeLine); 
        strcpy(writeLine, word); 
        strcat(writeLine, " "); 
       } 
      } 
     } 
    } 
    fprintf(writeFile, "%s\n", writeLine); 

se trouve la question originale ci-dessous:

Je suis en train d'écrire un programme de formatage de mots qui prend un fichier de données et le formate de sorte qu'il y ait jusqu'à un certain nombre de caractères par ligne. Je rencontre une erreur de segmentation en essayant de faire défiler les mots dans chaque ligne du fichier.

int readFile() 
{ 
    int rc = 1; 
    char readBuffer[ 256 ]; 
    char writeLine[ 256 ]; 
    char *word = malloc(numChars * sizeof(char)); 

    writeFile = fopen(writeName, "a"); 

    if ((openFile = fopen(readName, "r")) == NULL) 
    { 
     printf("Unable to open %s file for read\n", readName); 
     rc = 0; 
    } 
    else 
    {  
     while(fgets(readBuffer, sizeof(readBuffer), openFile) != NULL) 
     { 
      strncpy(writeLine, "", 0); 
      if (readBuffer[0] != EOF) 
      { 
       strncpy(word, strtok(readBuffer, " "), numChars -1); 
       while(word != NULL) 
       { 
        if(strlen(word) + strlen(writeLine) < numChars) 
        { 
         strcat(writeLine, word); 

Je reçois ici l'erreur:

     strncpy(word, strtok(NULL, " "), numChars -1); 
        } 
        else 
        { 
         fprintf(writeFile, "%s", writeLine); 
         strcpy(writeLine, word); 
         strncpy(word, strtok(NULL, " "), numChars -1); 
        } 
       } 
      } 
     } 
    } 

    return rc; 
} 

Je ne comprends pas pourquoi cela se passe. N'est-ce pas le point de strncpy que vous dites exactement combien de caractères à copier? Si je lui dis spécifiquement que copier des caractères jusqu'à un en dessous de la longueur de la chaîne, pourquoi y aurait-il un défaut de segmentation? EDIT: J'ai révisé le code à ce qui suit:

  strcpy(writeLine, strtok(readBuffer, " ")); 

      while(strcpy(word, strtok(NULL, " ")) != NULL) 
      { 
       if(strlen(word) + strlen(writeLine) < numChars) 
       { 
        strcat(writeLine, word); 
       } 
       else 
       { 
        fprintf(writeFile, "%s", writeLine); 
        strcpy(writeLine, word); 
       } 
      } 

Cela donne aucun changement dans l'opération, il est toujours une erreur de segmentation. Comment puis-je vérifier que le jeton est valide et toujours accéder au même jeton si c'est le cas?

+3

strtok renvoie NULL – shf301

+0

Pourriez-vous expliquer pourquoi il retournerait NULL et ce qui pourrait être fait pour le contourner? – thephfactor

+0

strtok renvoie NULL une fois qu'il atteint la fin de la mémoire tampon. Vous devez vérifier sa valeur de retour avant de le passer strncpy. Votre boucle while est également erronée car le mot ne sera jamais NULL. Votre boucle devrait boucler jusqu'à ce que la valeur de retour de strtok soit NULL. – shf301

Répondre

1

strncpy() ne pas se terminer si le nombre de caractères dans la limite est atteint. Vous devez annuler vous-même. Cela rend la déclaration strncpy(writeline, "", 0); ne rien faire (même pas terminer la chaîne). Ensuite, vous ajoutez sur cette chaîne non initialisée et il va mal.

1

N'est-ce pas le point de strncpy que vous lui dites exactement combien de caractères à copier?

NO. Le point est que vous lui dites combien de tampon vous avez disponible. Ensuite, il copie autant de caractères que possible dans ce tampon (en mettant à zéro le reste), et il ne se termine pas par zéro s'il y avait au moins autant de caractères disponibles que la taille de la mémoire tampon.

Personnellement, je ne l'utilise jamais; les alternatives qui génèrent toujours une chaîne comprennent strcpy, sprintf, snprintf, ou memcpy avec l'ajout manuel d'un terminateur null.

La lecture de la documentation des fonctions standard est toujours conseillée. strncpy(writeline, "", 0); ne fait rien.

Questions connexes