7
回答
c语言 指针问题,大神请帮忙
利用AWS快速构建适用于生产的无服务器应用程序,免费试用12个月>>>   
#include <stdio.h>
#include <stdlib.h>

char **file(const char file[]) {

    FILE *fp = fopen(file, "rb");
    if(!fp) {

        printf("\"%s\" The file can not be opened.\n", file);
        exit(1);

    }

    char buf[1024];
    unsigned int i = 0;
    char **str = (char **)malloc(sizeof(char **));

    while(fgets(buf, 1024, fp) != NULL) {

        str[i++] = buf;

    }

    fclose(fp);
    return str;

}

int main(unsigned int argc, char *argv[]) {

    char **str = file(argv[1]);
    printf("%s", str[atoi(argv[2])]);
    return 0;

}


为什么读出来都是文件的最后一行?
<无标签>
举报
好为
发帖于3年前 7回/239阅
共有7个答案 最后回答: 3年前
我重新贴下
//char buf[1024];
    char *buf = (char *) malloc(1024);
    unsigned int i = 0;
    char **str = (char **)malloc(sizeof(char **)*1000);

    while(fgets(buf, 1024, fp) != NULL) {

        str[i++] = buf;
        buf = (char *) malloc(1024); //上面代码 这里多次定义,copy 搞错了

    }

    fclose(fp);
    return str;



--- 共有 1 条评论 ---
Ivnoidea缓冲区都被刷掉了,保存缓冲区指针有什么用 3年前 回复
char **str = (char **)malloc(sizeof(char **));
这句是什么意思?是说只分配这么点空间吗?
那你能都存进去吗




你不保存字符串的内容,保存缓冲区的地址,每次fgets后,把缓冲区刷掉了,还有你的malloc是申请了一个四字节的内存,循环中其实已经数组越界了
这是你的 stack,和 heap 没有搞清楚,当 file 调用完后,局部变量的 char buf[1024] 的地址也就释放了,再次访问时,应该是出错的(linux 实验是这样),应该改为
//char buf[1024];
    char *buf = (char *) malloc(1024);
    unsigned int i = 0;
    char **str = (char **)malloc(sizeof(char **)*1000); // 假设少如 1000 行
 
    while(fgets(buf, 1024, fp) != NULL) {
 
        str[i++] = buf;
    	char *buf = (char *) malloc(1024);
 
    }



不知道你在什么环境下实验的,若是成功,而且都是读到最后一行也是符合逻辑的,因为你保存的地址都是 buf 这个变量的,所以都是文件的最后一行
--- 共有 4 条评论 ---
-10我这里实验时成功的,不知道你那里是报错,还是什么情况 3年前 回复
好为回复 @-10 : 还是不行哦! 3年前 回复
-10回复 @好为 : 刚刚修改了重新贴了下代码 3年前 回复
好为linux 环境, 我按你的方法来 还是不行。。。 还是最后一行 3年前 回复
str一直指向的是buffer,每次调用fgets,buffer都被刷新,当然输出的是最后一行。可以再while循环中加判断,读到特定行跳出。不过这写法,对指针的滥用。。。

引用来自“-10”的评论

这是你的 stack,和 heap 没有搞清楚,当 file 调用完后,局部变量的 char buf[1024] 的地址也就释放了,再次访问时,应该是出错的(linux 实验是这样),应该改为
//char buf[1024];
    char *buf = (char *) malloc(1024);
    unsigned int i = 0;
    char **str = (char **)malloc(sizeof(char **)*1000); // 假设少如 1000 行
 
    while(fgets(buf, 1024, fp) != NULL) {
 
        str[i++] = buf;
    	char *buf = (char *) malloc(1024);
 
    }



不知道你在什么环境下实验的,若是成功,而且都是读到最后一行也是符合逻辑的,因为你保存的地址都是 buf 这个变量的,所以都是文件的最后一行
坑不要这么挖,这种代码书写方式free的时候怎么处理?哈。不要带坏小朋友。。
--- 共有 4 条评论 ---
中山野鬼回复 @好为 : 哈,其他的不说了,你去看下ftell函数。。 3年前 回复
好为回复 @中山野鬼 : 我不确定文件大小啊 3年前 回复
中山野鬼回复 @好为 : 最简单的方法,你的文件不大,直接申请和文件大小的空间,然后,str[i]指向这个空间的不同位置就可以了。哈。 3年前 回复
好为那该怎么弄? 3年前 回复
顶部