首页
学习
活动
专区
工具
TVP
发布
社区首页 >问答首页 >将文件保存为特定线程中的字符串

将文件保存为特定线程中的字符串
EN

Stack Overflow用户
提问于 2018-02-04 11:20:12
回答 1查看 54关注 0票数 0

我试图在线程内将一个文本文件保存到C中的字符串中,但我总是得到一个分段错误。这发生在正在创建的线程的实例中。我以前没有使用过线程,所以我不确定这是否是导致问题的原因。

代码语言:javascript
复制
int getCurrentSegmentWordcount(int segment) { //declaring file pointer (value?)
    printf("func\n");
    char text[1000];
    char buffer[150];
    FILE *fp = fopen("words.txt", "r");
    if(fp == NULL) {
        printf("null file");
    }
    int i = 0;
    // while(feof(fp)) {
    //  text[i++] = fgetc(fp);
    // }
    // text[i] = '\0'; //set null char to end string

    while(fgets(buffer, 150, fp)) {
        strcpy(text[i], buffer);
        printf("\n\n %s \n\n", text[i]);
        i++;
    }
    getchar();

    pthread_exit(NULL);
}

下面是我的编译器警告。没有错误,但有多个警告。

代码语言:javascript
复制
assign2.c: In function ‘print_hello_world’:
assign2.c:10:9: warning: format ‘%d’ expects argument of type ‘int’, but argument 2 has type ‘void *’ [-Wformat=]
  printf("Hello World. Greetings from thread %d\n", tid);
         ^
assign2.c: In function ‘getCurrentSegmentWordcount’:
assign2.c:29:10: warning: passing argument 1 of ‘strcpy’ makes pointer from integer without a cast [-Wint-conversion]
   strcpy(text[i], buffer);
          ^
In file included from assign2.c:4:0:
/usr/include/string.h:125:14: note: expected ‘char * restrict’ but argument is of type ‘char’
 extern char *strcpy (char *__restrict __dest, const char *__restrict __src)
              ^
assign2.c:30:10: warning: format ‘%s’ expects argument of type ‘char *’, but argument 2 has type ‘int’ [-Wformat=]
   printf("\n\n %s \n\n", text[i]);
          ^
assign2.c: In function ‘main’:
assign2.c:46:77: warning: cast to pointer from integer of different size [-Wint-to-pointer-cast]
   status = pthread_create(&threads[i], NULL, getCurrentSegmentWordcount(i), (void * )i);
                                                                             ^
assign2.c:46:46: warning: passing argument 3 of ‘pthread_create’ makes pointer from integer without a cast [-Wint-conversion]
   status = pthread_create(&threads[i], NULL, getCurrentSegmentWordcount(i), (void * )i);
                                              ^
In file included from assign2.c:1:0:
/usr/include/pthread.h:233:12: note: expected ‘void * (*)(void *)’ but argument is of type ‘int’
 extern int pthread_create (pthread_t *__restrict __newthread,
            ^
assign2.c:52:7: warning: passing argument 1 of ‘exit’ makes integer from pointer without a cast [-Wint-conversion]
  exit(NULL);
       ^
In file included from assign2.c:3:0:
/usr/include/stdlib.h:543:13: note: expected ‘int’ but argument is of type 

‘void *’
     extern void exit (int __status) __THROW __attribute__ ((__noreturn__));
./assign2exec
Main here. Creating thread 0
func
Makefile:20: recipe for target 'all' failed
make: *** [all] Segmentation fault (core dumped)
EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2018-02-04 12:41:39

你要做的第一件事,就是阅读编译器警告,而不是忽略它们。他们在那里是给你暗示你做错了什么,他们不是在那里惹恼你。

函数strcpy具有以下签名:

代码语言:javascript
复制
#include <string.h>

char *strcpy(char *dest, const char *src);

从这里可以清楚地看出,它希望dest是指向char数组的指针,src指向的字符串将保存在该数组中。

你声明了char buffer[150];,所以buffer是一个char数组,buffer[i]将返回一个char。因此,您正在将错误的类型传递给strcpy

编译器会告诉你:

代码语言:javascript
复制
assign2.c: In function ‘getCurrentSegmentWordcount’:
assign2.c:29:10: warning: **passing argument 1 of ‘strcpy’ makes pointer from integer without a cast** [-Wint-conversion]
   strcpy(text[i], buffer);

你需要有一个2维的char数组或者一个char指针数组来保存它。第一个是最容易编写的:

代码语言:javascript
复制
char text[1000][1000];

唯一的问题是它在行数上有一个固定的长度,如果文件有超过1000行,你不能将它们全部存储在缓冲区中。

第二个选项更健壮:

代码语言:javascript
复制
int getCurrentSegmentWordcount(int segment) {
    char (*text)[1000] = NULL, char (*tmp)[1000];

    ...
    i = 0;
    while(fgets(buffer, sizeof buffer, fp)) {

        // removing possible \n from buffer, you probably
        // want that
        buffer[strcspn(buffer, "\n")] = 0;

        tmp = realloc(text, (i+1) * sizeof *tmp);
        if(tmp == NULL)
        {
            // error, cannot continue
            free(text);
            return;
        }

        text = tmp;
        strcpy(text[i], buffer);
        printf("\n\n %s \n\n", text[i]);
        i++;
    }
    ...

    free(text); // freeing the memory
}

而且这个版本甚至可以处理不同长度的行

代码语言:javascript
复制
int getCurrentSegmentWordcount(int segment) {
    char **text = NULL, **tmp;

    ...
    i = 0;
    while(fgets(buffer, sizeof buffer, fp)) {

        // removing possible \n from buffer, you probably
        // want that
        buffer[strcspn(buffer, "\n")] = 0;

        tmp = realloc(text, (i+1) * sizeof *tmp);
        if(tmp == NULL)
        {
            // error, cannot continue
            free(text);
            return;
        }

        text = tmp;

        text[i] = calloc(strlen(buffer) + 1, 1);

        if(text[i] == NULL)
        {
            // error, free all the allocated memory:
            for(int j = 0; j < i; ++j)
                free(text[j]);

            free(text);

            return;

        }

        strcpy(text[i], buffer);
        printf("\n\n %s \n\n", text[i]);
        i++;
    }
    ...

    // freeing the memory
    for(int j = 0; j < i; ++i)
        free(text[i]);

    free(text);
}

我不知道这是不是你的例子,但是你的函数是没有意义的。您将行存储在缓冲区中,但根本不对其执行任何操作。如果你返回了text或者用它做了些什么,这个函数会更有效率。

编译器警告和错误向您显示了需要改进代码的所有行。一行有趣的代码是:

代码语言:javascript
复制
assign2.c:52:7: warning: passing argument 1 of ‘exit’ makes integer from pointer without a cast [-Wint-conversion]
  exit(NULL);

正确的调用是

代码语言:javascript
复制
exit(0);
票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/48604348

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档