Bug aneh saat membaca dan mencetak string *char di C

Saya baru saja menemukan sesuatu yang sangat aneh. String char saya (sebut saja word) ternyata ada tambahan huruf saat saya print.
Surat yang dikontatenkan berbeda-beda tergantung pada:

  1. panjang kata awalan yang tepat.
  2. jumlah spasi setelah kata.

Saya menguraikan word dari line yang hanya berupa satu baris dari input standar. Saya menggunakan fungsi readWord untuk mengeluarkan word dari line:

void readWord(char **linePointer, char **wordPointer){
  char *line  = *linePointer;
  char *word = *wordPointer;
  while (!isEndOfLine(line) && isLowerCaseLetter(*line)){
    *word = *line;
    word++;
    line++;
  }
  word++;
  *word = '\0';
  printf("The retrieved word is: %s.\n", *wordPointer)
  *linePointer = line;
}

Input/output saya terlihat seperti ini (harap dicatat bahwa saya memanggil fungsi readWord SETELAH menangani insert dan spasi di antaranya):

// INPUT 1 :
insert foo
insert ba      // several spaces after 'ba'
// OUTPUT 2:
The retrieved word is foo.
The retrieved word is bas.

// INPUT 1 :
insert foo
insert ba      // several spaces after 'bar'
// OUTPUT 2:
The retrieved word is foo.
The retrieved word is bare.

Saya berpikir apakah saya mengalokasikan *word dengan benar dan saya rasa saya melakukannya:

root.word = (char *)malloc(sizeof(char *)); //root is my structure

Selain itu, kemungkinan besar hal ini tidak terkait dengan beberapa kesalahan dalam menetapkan ulang string word karena sudah sepenuhnya jelas di awal fungsi readWord().

Terima kasih atas bantuannya. Ini memang bug yang menantang bagi saya dan saya tidak tahu harus berbuat apa lagi.

PEMBARUAN

Ternyata saya sebenarnya mengalami beberapa masalah dalam pengalokasian/penugasan ulang, karena:

//INPUT
insert foo//no spaces
  insert bar                //spaces here
//OUTPUT
word variable before calling readWord function: ' '.
The retrieved word is foo.
word variable before calling readWord function: 'insert foo
'.
The retrieved word is bare.

person Mateusz Piotrowski    schedule 22.04.2015    source sumber
comment
Anda perlu mengalokasikan memori yang cukup untuk string yang Anda operasikan. Anda tidak melakukan itu.   -  person milleniumbug    schedule 22.04.2015
comment
word++ setelah loop terlalu banyak   -  person ryanpattison    schedule 22.04.2015
comment
@rpattiso Terima kasih! Itu benar. Namun word tidak dihapus setelah baris pertama, jadi hanya ada lebih dari satu bug. Saya akan mengerjakan apa yang dikatakan @milleniumbug.   -  person Mateusz Piotrowski    schedule 22.04.2015
comment
Aktifkan semua peringatan kompiler. Tindak lanjuti setiap peringatan tentang tipuan penunjuk, misalnya pada inkonsistensi while (!isEndOfLine(line) && isLowerCaseLetter(*line)) ini. Dan tambahkan ; di akhir baris printf().   -  person Weather Vane    schedule 22.04.2015


Jawaban (1)


Jangan pernah mempercayai masukan Anda, jadi periksalah spasi di awal kata.

Anda menambah satu kata terlalu banyak, seperti yang dicatat @rpattiso.

Saya ragu dengan alokasi memori Anda (Anda tidak menunjukkan kepada kami semua kode Anda): root.word = (char *)malloc(sizeof(char *)); mengalokasikan ruang untuk pointer ke sebuah karakter, tetapi tidak mengalokasikan ruang untuk karakter itu sendiri. readWord dapat melakukan itu.

Versi adaptasi berikut akan berfungsi (diperbarui):

void readWord(char **linePointer, char **wordPointer){
    char *line  = *linePointer;
    int i;

    while (!isEndOfLine(line) && !isLowerCaseLetter(*line)) line++; // go to begin of word
    *linePointer= line;
    while (!isEndOfLine(line) &&  isLowerCaseLetter(*line)) line++; // go to end of word

    i= line - *linePointer;                     // allocate room for word and copy it
    *wordPointer= malloc((i+1) * sizeof(char));
    strncpy(*wordPointer, *linePointer, i);
    (*wordPointer)[i]= '\0;

    printf("The retrieved word is: %s.\n", *wordPointer);
    *linePointer = line;
}
person Paul Ogilvie    schedule 22.04.2015
comment
Saya melihat bug besar. Saya memposting pembaruan (Kesalahan dalam strncopy) - person Paul Ogilvie; 22.04.2015
comment
Sebenarnya, kode ini tidak berfungsi untuk kata yang panjangnya satu huruf: insert v melempar segmentation fault 11. Itu macet ketika mencoba menjalankan baris *wordPointer[i]= '\0'. - person Mateusz Piotrowski; 23.04.2015
comment
Maaf, seharusnya (*wordPointer)[i]= '\0';. - person Paul Ogilvie; 23.04.2015