我这里有一个程序,假设是 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/