值geting在C中自动复制到指针

时间:2016-07-26 01:47:49

标签: 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.在运行调试器时我发现&#34; kl&#34;将第4行中的部分复制到选项卡作为其第三个元素(tab [2]),一旦读取该行就会发生这种情况(第scanf("%s",m_path);次第二次执行时)。因此,比较在该点成功,这不是期望的输出。我希望我清楚我的问题。

1 个答案:

答案 0 :(得分:1)

之后的一个循环中的变量!

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

#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个char指针的数组。您可以将指针指定给s1的开头。

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

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

然而,在你的情况下,你(幸运的是)没有得到分段错误,因此程序只检查了垃圾,因此无法提供正确的结果。

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

执行此操作的一种方法是:使tab使用{{s1制作一个2D数组,将<{}}指向的字符串深层复制,添加到tab[i] 3}}功能当然。

现在,当m_path超出范围时,tag根本就不在乎,因为它已经存储了自己的字符串,而不是指针!