簡體   English   中英

C中的fscanf,帶無空格的文本文件

[英]fscanf in C with a text file with no spaces

我有一個名稱如下的文本文件:

“MARY”, “PATRICIA”, “琳達”, “BARBARA”, “伊麗莎白”, “JENNIFER”, “MARIA”, “SUSAN”, “靄”,

我已經使用以下代碼嘗試將名稱放入數組:

char * names[9];
int i = 0;
FILE * fp = fopen("names.txt", "r");

for (i=0; i < 9; i++) {
  fscanf(fp, "\"%s\",", names[i]);
}

當我嘗試運行該程序時,出現了段錯誤。 我已經進行了仔細的調試,當我嘗試讀取第二個名稱時,我注意到故障出在這里。

有人知道我的代碼為什么不起作用,以及為什么分段錯誤正在發生嗎?

您的代碼中有未定義的行為 ,因為您沒有為在fscanf調用中寫入的指針分配內存。

您有九個未初始化指針的數組,並且由於它們是局部變量的一部分,因此它們具有不確定的值,即它們將指向看似隨機的位置。 寫入內存中的隨機位置(這會在您調用fscanf時發生)會做壞事。

解決問題的最簡單方法是使用數組數組,例如

char names[9][20];

這將為您提供9個數組的數組,每個子數組為20個字符(允許您使用最多19個字符的名稱)。

為了不超出范圍,您還應該修改通話,以免讀取太多字符:

fscanf(fp, "\"%19s\",", names[i]);

但是,使用fscanf函數還有另一個問題,那就是讀取字符串"%s"的格式將一直讀取,直到找到輸入中的空白為止(或者直到達到限制為止,如果字段寬度為提供)。

簡而言之:您不能使用fscanf來讀取您的輸入。

相反,我建議您使用fgets將整行立即讀取到內存中,然后使用例如strtok在逗號上分割字符串。


一種處理任意長行作為文件輸入的方法(偽代碼):

#define SIZE 256

size_t current_size = SIZE;
char *buffer = malloc(current_size);
buffer[0] = '\0';  // Terminator at first character, makes the string empty

for (;;)
{
    // Read into temporary buffer
    char temp[SIZE];
    fgets(temp, sizeof(temp), file_pointer);

    // Append to actual buffer
    strcat(buffer, temp);

    // If last character is a newline (which `fgets` always append
    // if it reaches the end of the line) then the whole line have
    // been read and we are done
    if (last_character_is_newline(buffer))
        break;

    // Still more data to read from the line
    // Allocate a larger buffer
    current_size += SIZE;
    buffer = realloc(buffer, current_size);

    // Continues the loop to try and read the next part of the line
}

// After the loop the pointer `buffer` points to memory containing the whole line

[ 注意:上面的代碼段不包含任何錯誤處理。]

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

int main(void) {
    char *names[9], buff[32];
    int i = 0;
    FILE *fp = fopen("names.txt", "r");

    for(i = 0; i < 9; i++) {
        if(1==fscanf(fp, "\"%31[^\"]\",", buff)){//"\"%s\"," does not work like that what you want
            size_t len = strlen(buff) + 1;
            names[i] = malloc(len);//Space is required to load the strings of each
            memcpy(names[i], buff, len);
        }
    }
    fclose(fp);
    //check print & deallocate
    for(i = 0; i< 9; ++i){
        puts(names[i]);
        free(names[i]);
    }
    return 0;
}

嘗試這個...

for (i=0; i < 9; i++) 
{
   names[i]=malloc(15);// you should take care about size
   fscanf(fp, "\"%s\",", names[i]);
}

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM