我正在尝试编写一个程序,将给定电话号码形成的字母的每个组合写入文件。我相当肯定,它会给segfault扫描用户要写入的文件名(主要是在其中),因为我已经进行了printf测试,但无法打印。由于某种原因,在添加递归函数之前,它不会给我一个段错误,但是在添加它们之后,它确实可以。
const char letters[8][5] = {"ABC", "DEF", "GHI", "JKL", "MNO", "PQRS", "TUV", "WXYZ"};
int main()
{
int userNum[7];
char userFile[25];
printf("Please enter the phone number you want to process with no added
characters or spaces: ");
scanf("%d", &userNum);
printf("Enter the file name (including extension and less than 25
characters) that you would like to write to.\n");
scanf("%s", userFile); //This is where I think the seg fault is happening
printf("Test"); //Because this doesn't print
FILE* file_ptr;
char fileName[17];
sprintf(fileName, "%s", userFile);
file_ptr = fopen(fileName, "w");
findWordsHelper(userNum, 7);
}
//Adding this function and the one after is what made the program start
//giving said seg fault
void findWords(int userNum[], int digit, char words[], int n)
{
printf("Test. n = %d", n);
int i;
if(digit == n)
{
printf("%s ", words);
return;
}
for(i = 0; i < strlen(letters[userNum[digit]]); i++)
{
words[digit] = letters[userNum[digit]][i];
findWords(userNum, digit+1, words, n);
if(userNum[digit] == 0 || userNum[digit] == 1)
{
return;
}
}
}
void findWordsHelper(int userNum[], int n)
{
printf("test");
char result[n+1];
result[n] = '\0';
findWords(userNum, 0, result, n);
}
答案 0 :(得分:1)
我不在可以测试的环境中,但是我看到了一些东西。首先,您的printf测试不会打印,因为如果没有换行符。如果您不打算放入,请致电fflush。例如
printf("test");
fflush(stdout);
第二,您使用scanf
来读取电话号码显示了一些关于scanf
如何将输入视为整数的误解。为此,您不需要7个整数的数组,因为您只是指示输入不要包含多余的字符。因此,将像345-6789这样的电话号码输入为3456789
,该电话号码将被读取为一个整数:即3,000,000、4,55.6万,7,900,89。这将被读取为一个整数。我知道您想将它们视为单独的数字,但是scanf
在不使用空格分隔时会将其视为1的数字。要读入单个int,就足够了:
...
int phoneNumber;
scanf("%d", &phoneNumber); // <--- notice the & operator
编辑
我正在阅读scanf()
的手册页,当使用%s
说明符时,它应该在字符串中插入一个空字符。因此,指示检查退货并确保在其中放置'\0'
字符的部分不适用。
编辑2
我今天早上有一刻,不得不弄清楚这一点。我想我明白了。函数findWords()
中的某些内容看起来有些可疑,并且进行了编译,段错误,并且查看核心文件表明情况确实如此。该功能就是这一行
for(i = 0; i < strlen(letters[userNum[digit]]); i++)
具体地说,它是对strlen()
的调用,其结果是使用userNum[]
索引到letters[]
中。正如我自己和其他人所指出的那样,scanf()
不会将“ 3456789
”之类的“电话号码”读取为7个不同的整数值。它被读取为单个int,并将被读取到userNum[0]
中(发生段错误时,您猜怎么着?digit = 0
)。毫不奇怪,letters
数组不包含 300万,400 56000、700 89指数。 (假设输入的号码是我写的。)
正如Jasen(我认为)所提到的,int对于电话号码并不是很有效。至少,您必须开发出一种不同的方式来分解电话号码以用作索引。
答案 1 :(得分:0)
首先,缺少printf输出并不表示该程序未在该点之后执行,因为输出可能已被缓冲。
您可以在printf调用后立即执行fflush(stdout),也可以将setvbuf与null参数一起使用来强制取消缓冲。
第二,在递归函数中,每次调用都会导致自身调用,直到您的for循环中的迭代次数为止。我怀疑那里存在逻辑错误,并且递归调用的数量可能会激增。
第三,您在这里肯定有一个逻辑问题:
int userNum [7]; ... scanf(“%d”,&userNum);
看起来您期望如果用户输入“ 1234567”,则每个userNum [i]都包含一个数字,但这不是正在发生的情况。
scanf会将参数视为指向int的指针,例如在32位CPU上,它将整数值1234567放入“ userNum”的前4个字节中。实际上,如果CPU无法将整数(无论是16位还是32位)写入未对齐的地址,则此可能会在此处引起段错误。由于userNum实际上是一个数组,因此它可能适合也可能不适合整数。
答案 2 :(得分:0)
int main() {
int userNum[7];
char userFile[25];
printf("Please enter the phone number you want to process with no added"
" characters or spaces: ");
printf("Enter the file name (including extension and less than 25 "
" characters) that you would like to write to.\n");
scanf("%s", userFile); //This is where I think the seg fault is happening
应该是:
scanf("%24s",userfile);
读取的字符数不得超过24个字符。
char fileName[17];
sprintf(fileName, "%s", userFile);
但是userfile可以是24个长...并且只能容纳16个,所以应该是。
sprintf(fileName, "%.16s", userFile);
可消除任何溢出。