c - 在 C 中自动将值复制到指针

标签 c arrays string pointers

我这里有一个程序,假设是 this 的解决方案问题。

我的代码是这样的:

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


 int compare(char *,char*[],int);

 int compare(char *s,char *tab[],int i)
{
  int j=0;
  for(;j<i;j++) {
    if(strcmp(s,tab[j])==0)
        return 1;
  }
  return 0;
}

 int main(){

  int T=0,N=0,M=0,cas=0;
  char g_path[100]={0},*tab[10000]={0};

  int i=0;

  /*#ifndef judge
    freopen("input.txt","r",stdin);
    freopen("output.txt","w",stdout);
  #endif*/

  scanf("%d",&T);

  while(T--) {
    scanf("%d %d",&N,&M);
    int cnt=0;
    i=0;
    while(N--) {
        scanf("%s",g_path);
        char *s = strtok(g_path,"/");
        while(s!=NULL) {
            tab[i++]=s;
            s=strtok(NULL,"/");
        }
    }

    while(M--) {
        char m_path[100]={0};
        scanf("%s",m_path);
        char *s1 = strtok(m_path,"/");  //problem here
        while(s1!=NULL) {
            int k=compare(s1,tab,i);
            if(k==0){
                cnt++;
                tab[i++]=s1;
            }
            s1=strtok(NULL,"/");
        } 
    }
    printf("Case #%d: %d\n",(cas++)+1,cnt);
}
}

问题是假设输入是:

1
0 2
/hhh/jjj/kk
/hhh/jjj/kl

假设输出为4,即需要创建的目录数为4。

但我获得的输出是 3。在运行调试器时,我发现第 4 行中的“kl”部分作为其第三个元素 (tab[2]) 被复制到选项卡中,这在它读取时立即发生行(一旦 scanf("%s",m_path); 第二次执行)。因此,比较在不是所需输出的那一点成功。我希望我清楚我的问题。

最佳答案

循环内的变量之后会超出范围!


这是您提到的案例的固定代码(确保测试更多案例并在需要时进行调试):

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


// UNNEEDED int compare(char *,char*[],int);

int
compare(char *s, char tab[10000][100], int i)
{
    int j = 0;
    for (; j < i; j++) {
    if (strcmp(s, tab[j]) == 0)
        return 1;
    }
    return 0;
}

int
main()
{
    int T = 0,
    N = 0,
    M = 0,
    cas = 0;
    char g_path[100] = { 0 }, tab[10000][100] = { {0} };

    int i = 0;
    scanf("%d", &T);

    while (T--) {
    scanf("%d %d", &N, &M);
    int cnt = 0;
    i = 0;
    while (N--) {
        scanf("%s", g_path);
        char *s = strtok(g_path, "/");
        while (s != NULL) {
            strcpy(tab[i++], s);
            s = strtok(NULL, "/");
        }
    }

    while (M--) {
        char m_path[100] = { 0 };;
        scanf("%s", m_path);
        char *s1 = strtok(m_path, "/"); // problem here
        while (s1 != NULL) {
            int k = compare(s1, tab, i);
            if (k == 0) {
                cnt++;
                strcpy(tab[i++], s1);
            }
            s1 = strtok(NULL, "/");
        }
    }
    printf("Case #%d: %d\n", (cas++) + 1, cnt);
    }
    return 0;
}

输出:

C02QT2UBFVH6-lm:~ gsamaras$ pico main.c
C02QT2UBFVH6-lm:~ gsamaras$ gcc -Wall main.c
C02QT2UBFVH6-lm:~ gsamaras$ ./a.out
1
0 2
/hhh/jjj/kk
/hhh/jjj/kl
Case #1: 4

所以发生了什么?您使用的是 tab,这是一个包含 10000 个字符指针的数组。您可以将指针分配给 s1 的开头。

但是,s1 将指向 m_path,它是在 while(M--) 循环中创建的嵌套变量。因此,当循环开始时,m_path 被创建,当循环终止时,m_path 超出范围并因此被销毁。

所以当你要检查你的第二个案例时,你会检查 tab 现在(因为它被分配给 s1,它被分配给 m_path ) 指向无效数据,即超出范围的数据,导致未定义的行为

但是,在您的情况下,您很(不幸)没有遇到段错误,因此程序只是检查垃圾,因此无法提供正确的结果。


我是如何解决你的问题的?

一种方法是:将 tab 设为二维数组,然后将 s1 指向的字符串深度复制 tab[i],使用 strcpy()当然是函数。

现在,当 m_path 超出范围时,tag 根本不在乎,因为它内部存储的是字符串本身,而不是指针!

关于c - 在 C 中自动将值复制到指针,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/38579885/

相关文章:

c - C 中动态分配的二维数组

c - 打印数组中的第一个索引会使用 C 打印每个索引

Java正则表达式替换文本中的字符串

c++ - 我如何在 C++ 中对包含 double 值的字符串强制执行精度

c - c中的TCP套接字

c - 为什么不使用fread读取目录文件?

c++ - 交换函数不交换 C++ 中二维数组的元素

python - matplotlib 从 1D 数组创建 2D 数组 - 有更好的方法吗?

java - 仅当输入为 "true"或 "false"时才将字符串转换为 boolean 值

c# - 将此行放入 excel.Formula "=IF(C4 = "x";1;0 )"isnt working because of double ` ""`