【问题标题】:Why is my printf() not printing the first character in the text file?为什么我的 printf() 不打印文本文件中的第一个字符?
【发布时间】:2018-12-12 14:44:53
【问题描述】:

我是一个菜鸟 C 程序员。 我无法读取文本文件的所有字符。 我的 file.txt 有数字:9,2,3,4,5,6 但是当我运行下面编写的代码时,它只是跳过 9 并打印其余的数字。但是,当我在 9 之前放置一个空格时,它运行得很好。我如何解决它?为什么会这样?

FILE* fp;
fp = fopen("file.txt", "r");
int a[10];
char ch;

while((ch=getc(fp))!= EOF)
{
    fscanf(fp, "%d", &a[ch]);
    printf("%d ", a[ch]);
}

提前致谢;

【问题讨论】:

  • a[10] 太小,无法被 ascii 字符索引!你把它放在你的记忆之外:未定义的行为。
  • 另外,getc 获取一个字符,在您的情况下是第一个 9,然后读取 2fscanf,然后读取 3getc。 ...等
  • ..我不确定你想做什么。这一切看起来都很笨拙。
  • 注意getc()返回的是int的值,而char可能无法持有EOF,所以char ch; --> int ch;

标签: c file error-handling file-handling


【解决方案1】:

while((ch=getc(fp))!= EOF) 中的函数getc 使用文件中的单个字符;如果9 是文件中的第一个字符,它将被简单地读入ch 并且 - 由于您的字符集可能是 ASCII - 将设置为 ch==0x39

因此 (1) 9 将不再可用于 fscanf(fp, "%d", &a[ch]);;这就是你认为它被“跳过”的原因。

(2) 在ch 位置写入a 然后超出a 的数组边界。

【讨论】:

  • 那么,我应该怎么做才能有效地读取或扫描文件中的所有整数呢?
  • @Xedron 你能解释一下为什么你使用ch 作为你的 a[] 数组的索引吗?你输入的文件是什么样的。很难提供帮助,因为您的代码不仅仅是从文件中读取整数。
【解决方案2】:

目前尚不清楚您的文件中有多少int,并且当前存储它们的方式容易出错。 fgetc 返回一个 intEOF (-1) 或 0-255,所以 ch 应该被声明为 int 然后当 (ch=getc(fp))!= EOF 为真时,ch 将包含 0- 255. 在下面的fscanf(fp, "%d", &a[ch]); 中,您再次从文件中读取,但读取到索引位置ch 的数组中,这显然不是您的意图(当您读取值> 9 的字符时,它也可能会崩溃。提示: '0' 的值为 48)。下面的解决方案可能看起来过于复杂,但我已经习惯了 C++,这些事情发生在幕后,你不必为此烦恼太多。也许你会通过去腌制得到一些想法。

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

/* dynamic memory storage - start */
typedef struct {
    size_t m_size;
    size_t m_reserved;
    int* m_data;
} store;

/* create a store */
store* store_create() {
    store* s = malloc(sizeof(store));
    if(s) {
        /* initialize values */
        s->m_size = 0;
        s->m_reserved = 1; /* a very conservative start value */
        s->m_data = malloc(sizeof(int)*s->m_reserved);
        if(s->m_data==NULL) {
            free(s);
            s = NULL;
        }
    }
    return s;
}

/* destroy a store */
void store_destroy(store* s) {
    /* free the integer array */
    free(s->m_data);
    /* free the store struct */
    free(s);
}

bool store_reserve(store* s, size_t new_res) {
    /* reserve more space for the int's if needed */
    if(new_res>s->m_reserved) {
        int* n = realloc(s->m_data, sizeof(int)*new_res);
        if(n==NULL) return false; /* could not expand storage */
        s->m_reserved = new_res;
        s->m_data = n;
    }
    return true;
}

// check if it's time to increase reserved storage
bool store_check_reserve(store* s) {
    if(s->m_size == s->m_reserved)
        /* change 5/4 to a larger value for more aggressive
         * increase of memory allocation */
        return store_reserve(s, (s->m_reserved+1)*5/4);
    else
        return true;
}

// add a value to the store
bool store_add(store* s, int v) {
    if(!store_check_reserve(s)) return false;

    s->m_data[s->m_size++] = v;
    return true;
}

/* dynamic memory storage - end */

int main(int argc, char* argv[]) {
    FILE* fp;
    fp = fopen("file.txt", "r");

    /* create a store for our unknown amount of int's */
    store* myStore = store_create();

    /* scan for strings separated by comma and newline
     * and allocate memory for it */
    char* str;
    while(fscanf(fp, " %m[^,\n],", &str)==1)
    {
        int num;
        /* convert string to integer */
        if(sscanf(str, "%d", &num)==1) {
            /* store the extracted value */
            if(store_add(myStore, num)==false) {
                fprintf(stderr, "FAILED STORING %d\n", num);
            }
        }
        // free string allocated by fscanf (%m) */
        free(str);
    }
    fclose(fp);

    printf("All %d stored values:\n", myStore->m_size);
    for(size_t i=0; i<myStore->m_size; ++i) {
        printf("%d = %d\n", i, myStore->m_data[i]);
    }

    /* release memory allocated by our store */
    store_destroy(myStore);
    return 0;
}

【讨论】:

    猜你喜欢
    • 2015-04-25
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-07-05
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多