簡體   English   中英

使用指針將文件中的字符串輸入到 C 中的二維字符數組中

[英]Use a pointer to enter strings from a file into a 2D char array in C

我無法將文件中的字符串輸入到我的二維字符數組(字符串數組)中。 我需要用指針來做,但是,它會產生最后一個和倒數第二個單詞的奇怪混亂。 另外,我不能使用字符串庫函數。

到目前為止,這是我的代碼:

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

int main()
{
    FILE *fin, *fout;
    char lineRead[20], arr2[20][20];
    int i, j, k, len;


    fin = fopen("cp4in_1.txt","r");
    if (fin){
        while(fscanf(fin,"%s",&lineRead) != EOF){
            char *pointer = lineRead;
            for (k = 0; lineRead[k] != '\0'; k++);
            for (i = 0; i < 4; i++){
                for (j = 0; j < k; j++){
                    arr2[i][j] = *pointer;
                    pointer++;
                }
            }
        }
    }
    else{
        printf("Couldn't find file.\n");
    }
}

這是 cp4in_1.txt:

ABCDE
PQRSTFG
acegikmoqsuwyz
bdfhjlnprtvx

我正在尋找的結果應該讓 arr2 包含一個字符串數組,表示"ABCDE""PQRSTFG""acegikmoqsuwyz""bdfhjlnprtvx"

你應該總是用\\0終止你的字符串,所以:

          for (i = 0; i < 4; i++){
                for (j = 0; j < k; j++){
                    arr2[i][j] = *pointer;
                    pointer++;
                }
                arr2[i][j]='\0';
            }

你的程序也需要一些改變

int main()
{
    FILE* p;
    p = fopen("file.txt", "r+");

    int i = 0, j, k;
    char* pointer, lineRead[20], arr2[20][20];
    if (p != NULL)
    {
        while (!feof(p))
        {
            fscanf(p, "%s", &lineRead);
            for (k = 0; lineRead[k] != '\0'; k++);
            pointer = lineRead;
            for (j = 0; j < k; j++)
            {
                arr2[i][j] = *pointer;
                pointer++;
            }
            arr2[i][j] = '\0';
            i++;
        }
        for (int i = 0; i < 4; i++)
        {
            printf("%s\n", arr2[i]);
        }
    }
    else
    {
        printf("Couldn't find file.\n");
    }
    return 0;
}

您面臨的最大問題是嘗試使用格式化輸入函數進行面向行的輸入 (而且你用錯了)對於新的 C 程序員來說,使用fscanfscanf函數系列)充滿了陷阱。 在您知道它們是什么之前,請避免使用它們,而是使用面向行的輸入函數fgets()或 POSIX getline()以確保每次都消耗整行輸入。

在您的情況下,數組lineRead在訪問時衰減為指針, C11 Standard - 6.3.2.1 Other lineRead - Lvalues, arrays, and function designators(p3) ,因此您使用&lineRead是錯誤的(導致fscanf()參數具有鍵入char **而不是正確的char* )。 不需要'&'因為lineRead已經是一個指針,因此正確的用法是:

  while(fscanf(fin,"%19s",lineRead) == 1){

注意:您還必須提供場寬度調節,以限制字符什么將適合讀lineRead -包括NUL終止字符,否則你用fscanf()是不超過使用安全gets() - - 已從 C11 中完全刪除)

這只是使用scanf系列的眾多陷阱之一。

相反,使用面向行的輸入函數,您可以執行以下操作:

#include <stdio.h>

#define ROWS   20
#define COLS ROWS   /* if you need a constant, #define one (or more) */

int main (int argc, char **argv) {

    char arr[ROWS][COLS];
    size_t n = 0;
    /* use filename provided as 1st argument (stdin by default) */
    FILE *fp = argc > 1 ? fopen (argv[1], "r") : stdin;

    if (!fp) {  /* validate file open for reading */
        perror ("file open failed");
        return 1;
    }

    /* while array not full, read line into array */
    while (n < ROWS && fgets (arr[n], COLS, fp)) {
        char *p = arr[n];           /* pointer to start of string */
        do {                        /* loop until '\n' found */
            if (*p == '\n')  
                *p = 0;             /* overwrite with nul-terminating char */
        } while (*p && *++p);
        n++;                        /* increment line counter */
    }

    if (fp != stdin)   /* close file if not stdin */
        fclose (fp);

    for (size_t i = 0; i < n; i++)  /* output stored lines */
        printf ("line %2zu : %s\n", i, arr[i]);
}

使用面向行的輸入函數, '\\n'從輸入中讀取並包含在填充的緩沖區中。 您唯一的工作是從緩沖區中刪除尾隨的'\\n' 這通常是通過例如arr[n][strcspn(arr[n], "\\n")] = 0; ,但因為你不能使用string.h一個簡單的循環就可以了。

示例使用/輸出

使用dat/cp4int_1.txt的輸入文件,您可以將文件名作為第一個參數傳遞給程序並接收以下輸出:

$ ./bin/readcp4int_1 dat/cp4int_1.txt
line  0 : ABCDE
line  1 : PQRSTFG
line  2 : acegikmoqsuwyz
line  3 : bdfhjlnprtvx

仔細檢查一下,如果您還有其他問題,請告訴我。

主要問題是您在 while 循環中遍歷 arr[i] 並且不要忘記在每個字符串的末尾放置 '\\0' 。 此外,您在 while 循環中多次聲明 char 指針,這也是錯誤。

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

int main()
{
    FILE *fpin, *fpout;
    char lineRead[20], arr2[20][20], *pointer;
    int i = 0, j, k, len;


    fpin = fopen("cp4in_1.txt","r");
    if (fpin){
        while(fscanf(fpin,"%s", lineRead) != EOF){
        pointer = lineRead;
        for (k = 0; lineRead[k] != '\0'; k++);
        for(j = 0; j < k; j++){
            arr2[i][j] = *pointer;
            pointer++;
        }
        arr2[i][j+1] = '\0';//place zero char at the end of the string
        i++;
        if(i >= 4)
            break;
        }
    }
    else{
        printf("Couldn't find file.\n");
    }
    //output the result
    for(i = 0; i < 4; i++){
    printf("%s\n", arr2[i]);
    }

    return 0;
}

輸出:

ABCDE
PQRSTFG 
acegikmoqsuwyz
bdfhjlnprtvx

暫無
暫無

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

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