我正在尝试制作一个程序,该程序将给定电话号码形成的每个字母组合写入文件。我相当肯定它给出了段错误,我扫描了用户想要写入的文件的名称(主要是),因为我已经进行了 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] = ' ';
findWords(userNum, 0, result, n);
}
我不在一个可以测试的环境中,但我看到了一些东西。首先,您的 printf 测试没有打印,因为 if 没有换行符。如果你不打算放一个,打电话给fflush。 例如
printf("test");
fflush(stdout);
其次,您使用scanf
来读取电话号码表明scanf
如何将输入视为整数存在一些误解。为此,您不需要 7 个整数的数组,因为您只是指示输入没有多余的字符。因此,像 345-6789 这样的电话号码被输入为3456789
将被读取为单个整数:即 300 万、4 56 千、7 百 89。这将读入单个整数。 我知道您想将它们视为单独的数字,但是当不用空格分隔时,scanf
会将它们视为 1 个数字。 要读入单个整数,这就足够了:
...
int phoneNumber;
scanf("%d", &phoneNumber); // <--- notice the & operator
编辑我正在阅读手册页scanf()
,当使用%s
说明符时,它应该在字符串中插入一个空字符。 因此,指示检查退货并确保将' '
字符放置在那里的部分不适用。
编辑 2我今天早上有一会儿时间,必须弄清楚这一点。 我想我已经知道了。 函数中的某些东西看起来有点可疑findWords()
编译、隔离错误以及查看核心文件表明情况确实如此。 这是该函数中的这一行
for(i = 0; i < strlen(letters[userNum[digit]]); i++)
具体来说,它是对strlen()
的调用,其结果是使用userNum[]
索引到letters[]
中。 正如我和其他人所指出的那样,scanf()
不会将诸如3456789
(输入)之类的"电话号码"读取为 7 个不同的整数值。 它被读取为单个 int,它将被读入userNum[0]
(你猜怎么着?digit = 0
段错误发生时)。 这并不奇怪,letters
阵中没有300万,45.6万,789猥不。(假设输入的数字是我写的。
正如 Jasen 所提到的(我认为),int 对于电话号码并不真正有效。 至少,您必须开发一种不同的方法来分解电话号码以用作索引。
首先,缺少 printf 输出并不表示程序没有执行超过该点,因为输出可能是缓冲的。
您可以在 printf 调用后立即执行 fflush(stdout),也可以使用带有空参数的 setvbuf 来强制取消缓冲。
其次,在递归函数中,每次调用都会导致调用自身,直到 for 循环中的迭代次数。我怀疑那里有逻辑错误,递归调用的数量可能会爆炸。
第三,你肯定有一个逻辑问题:
int userNum[7]; ... scanf("%d", &userNum);
看起来您期望如果用户输入"1234567",则每个userNum[i]都包含其中一个数字,但事实并非如此。
scanf 会将参数视为指向 int 的指针,例如在 32 位 CPU 上,它会将整数值1234567放入"userNum"的前 4 个字节中。事实上,如果 CPU 无法将整数(无论是 16 位还是 32 位)写入未对齐的地址,这可能会导致段错误。由于userNum实际上是一个数组,因此它可能会也可能不适合整数对齐。
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);
但是用户文件可能是 24 长...这只能容纳 16 个,所以应该是。
sprintf(fileName, "%.16s", userFile);
这会切断任何溢出。