【问题标题】:Dealing with strings in C在 C 中处理字符串
【发布时间】:2013-04-08 05:34:34
【问题描述】:

我正在尝试用 C 语言编写一个流编辑器,但我很难处理字符串。在读取文件的行后,我想将它们本地存储在字符串数组中。但是,当我尝试将变量 temp 存储到字符串数组 StoredEdits 中时,我收到 segmentation fault (core dumped) 错误。此外,如果我取消注释 char* temp2 变量并将其保存到我的数组中作为一种解决方法,那么最后读取的值将存储在数组中的每个值中。

我认为这与 temp2 是一个指针这一事实有关。在每次迭代后,我已经尝试了一百万种方法,例如 malloc'ing 和 free'ing 这个变量,但似乎没有任何效果。

任何帮助将不胜感激。

      #define MAX_SIZE 100 
      typedef char String[MAX_SIZE];   
          int main(int argc, char* argv[]){
              char** StoredEdits;                                                                                                                                                                    
              int index, numOfEdits;
              FILE *EditFile;                                                                                                                                                                                       
              char* temp;
              //char* temp2;                                                                                                                                                                                            

              StoredEdits = (char**)malloc(MAX_INPUT_SIZE*sizeof(String));                                                                                                                                           

              /*Check to see that edit file is passed in.*/
              if(argc < 2){
                printf("ERROR: Edit File not given\n");
                return(EXIT_FAILURE);
              }

              printf("%s\n",argv[1]);

              if( (EditFile = fopen(argv[1],"r")) != NULL ){
                printf("file opened\n");
                numOfEdits = 0;
                while(fgets(temp, MAX_STRING_SIZE, EditFile) != NULL){
                  printf("%d %s",numOfEdits,temp);
                  //temp2 = temp;                                                                                                                                                                                       
                  StoredEdits[numOfEdits++] = temp;
                  //StoredEdits[numOfEdits++] = temp;
                  printf("Stored successfully\n");
                }

..........

              printf("%d\n",numOfEdits);
              for(index=0;index<numOfEdits;index++){
                printf("%d %s\n",index, StoredEdits[index]);
              }

【问题讨论】:

标签: c string segmentation-fault fgets


【解决方案1】:

您需要初始化 temp 以指向有效存储。

temp = malloc(MAX_STRING_SIZE+1);

看起来您可能打算这样做:

String temp;

使用您的宏。这作为一个常规的 char 数组会更好。它的通用名称是 buffer

char buffer[MAX_STRING_SIZE+1];

然后,您应该在数组中存储,而不是 temp 本身,而是包含内容副本的新字符串。有一个 POSIX 函数 strdup 在这里应该会有所帮助。请注意,strdup 不是 C 标准的一部分,但它在大多数托管实现中都可用。从历史上看,它来自 BSD 分支。

StoredEdits[numOfEdits++] = strdup(temp);

让我稍微退后一步说,如果您为循环中的temp 分配新存储,那么您应该跳过strdup,因为正如吉姆巴尔特所说,这将泄漏内存。如果您在循环之外分配temp,那么无论您是静态分配(通过声明char [])还是动态分配(使用malloc)都没有什么区别。


顺便说一句,这条线不会给你买多少:

typedef char String[MAX_SIZE];

关于原因,请参阅经典的 Kernighan(K&R 中的 K)文章 Why Pascal is not my favorite Programming Language


另外请注意,我上面的示例不检查malloc 返回的指针。 malloc 可能会失败。当malloc 失败时,它将返回一个 NULL 指针。如果您尝试通过此指针存储数据,Kaboom!

【讨论】:

  • 如果你将temp 设置为mallocstrdup 的结果,你会泄漏内存。要么使用malloc 并跳过strdup,或者(我认为更好,因为它不会浪费内存),使用堆栈上的缓冲区并strdup 它。
  • strpdup!正是我想要的。非常感谢!
  • @JimBalter 如果我在每次迭代后释放(temp)它还会泄漏吗?
  • @aensm 这将修复泄漏,但是 strdup 在很大程度上是多余的。它会产生缩小存储空间以完全适合字符串的副作用。如果你有大量的它们,那可能很重要。
【解决方案2】:

由于指针语义,您的问题是正确的。您应该使用从 temp 复制字符串的内容。

char *cpy = malloc(1 + strlen(temp));
if (cpy)
    strcpy(cpy, temp);
//else handle error
StoredEdits[numOfEdits++] = cpy;

【讨论】:

  • 这被标记为 C。C++ 是一种不同的语言,就该语言而言的答案是不合适的。
  • 哦,好尴尬。直到现在我才注意到。然后我会编辑我的答案。
  • 不幸的是,我必须使用 C 而不是 C++,所以我认为使用该字符串类是不可能的。我也尝试了 strcpy,但也出现了分段错误。
  • FWIW 我更新了我的答案,使其更像我在 C 中所做的。
  • +1 我真的很感激您最初发布了有关 C++ 的信息。几乎可以肯定,它吓跑了所有打字速度比我快的 C 忍者。 :)
【解决方案3】:

其他人回答了错误的原因。

但是从程序中,我看到您试图分配一个字符双精度数组。然后将从文件中读取的每一行存储到数组中。

StoredEdits = (char**)malloc(MAX_INPUT_SIZE*sizeof(String));

如果我的假设是正确的,那么您应该将数组传递给 strcpy,如下所示。

strcpy(StoredEdits[numOfEdits],tmp);

当你有一个每行大小不同的文件时,最好将指针数组指向字符数组。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2012-10-01
    • 1970-01-01
    • 1970-01-01
    • 2014-05-04
    • 2010-11-14
    • 2010-09-24
    • 1970-01-01
    相关资源
    最近更新 更多