【问题标题】:strcpy not working inside for loop? c programmingstrcpy 在 for 循环中不起作用? c编程
【发布时间】:2021-11-28 19:12:45
【问题描述】:

我正在编写一个循环遍历具有两列的文本文件的程序。第一个值是字符串,第二个是整数。我正在尝试根据它们的列将它们放入数组中。

数据示例:

斯蒂芬 170

谢恩 150

杰克 180

我正在尝试这样做:

[“斯蒂芬”、“肖恩”、“杰克”]

[170,150,180]

由于某种原因,strcpy 函数不起作用。我没有收到错误消息,但是当我使用 strcpy 并尝试打印字符串数组的第一个值时,没有任何反应。

#include <stdio.h>
#include <string.h>

int main (void) {
    FILE* dict;
    char word[50];
    int weight;
    int weights[50000]; 
    char *words[50000];

    dict = fopen("dict.txt", "r");

    for (int i = 0; i < 50000; i++) {
        fscanf(dict, "%s  %d", &word, &weight);
        weights[i] = weight;
        strcpy(word, words[i]);
    }

    printf("%s", words[0]);
    printf("%d", weights[0]);
    return 0;
}

【问题讨论】:

  • 你读到word,然后将strcpy(destination, source)读到word - 投票结束是一个错字。

标签: c strcpy


【解决方案1】:

您在调用 strcpy 时交换了目的地和来源。

检查 man 或使用显示 lib 函数原型的良好 IDE 应该可以帮助您永远避免这种愚蠢的错误。

另外,幸运的是程序没有出现段错误,因为您正在从 words[i] 读取,这是一个未初始化的字符指针数组,您应该在复制到它之前添加一个 words[i] 的 malloc。

该程序的最小修复(还有其他问题需要修复)版本可能如下所示

#include<stdio.h>
#include <string.h>
#include <stdlib.h>
int main (void)
{
FILE* dict;
char word[50];
int weight;
int weights[50000]; 
char *words[50000];


dict = fopen("dict.txt", "r");
for (int i = 0; i < 50000; i++) {
    fscanf(dict,"%s  %d", &word, &weight);
    weights[i] = weight;
    words[i] = malloc(strlen(word)+1);
    strcpy(words[i], word);
}
printf("%s", words[0]);
printf("%d", weights[0]);
return 0;
}

另一种选择是使用strdup 而不是当前代码,因为它同时使用mallocstrcpy

其他明显的问题是,如果任何单词超过 50 个字符,您的程序就会出现问题,并且使用 scanf 修复并非易事。您可以使用fscanf(dict,"%49s %d", &amp;word, &amp;weight); 之类的东西来避免单词溢出,但是如果单词太长会破坏解析循环。 (你会得到一个单词开头的行和之前的权重值)。

如果您的字典文件少于 50000 个条目,则会出现另一个问题。

假设您的字典文件的内容具有预期的格式,而不是修复代码。

【讨论】:

  • 没错,但也存在其他重大问题。
  • 确实,需要一些内存分配,我将其添加到我的答案中。但显然指针指向某个地方(未初始化),否则他会得到一个段错误。
【解决方案2】:

首先注意strcpy的参数顺序不对:第一个是目标,第二个是源,我猜你想把word字符串复制到word[i],所以你需要交换参数顺序。

但是这也不起作用,因为word[i] 指向垃圾内存。你必须分配一些。例如,您可以改用 strdup

words[i] = strdup(word);

请注意,它在堆上分配内存,所以不要忘记在使用完后释放它。

【讨论】:

  • 值得一提的是,strdup 实际上不在 C 标准中。不过,它很可能会在 C23 中。
  • 因为它是主要的,分配的内存将在函数结束时被释放。文件描述符也将被关闭。当然,如果不是因为流程结束,两者都应该得到照顾。
猜你喜欢
  • 1970-01-01
  • 2020-03-30
  • 1970-01-01
  • 1970-01-01
  • 2017-04-13
  • 2013-12-31
  • 2017-01-14
  • 2011-07-21
  • 2016-02-05
相关资源
最近更新 更多