我的任務是像在舊手機中一樣制作 t9 之類的東西(數字也可以表示某些字母組合)。例如,如果用戶以這種方式運行它./t9search 23 < list.txt,程式應該回傳具有對應于它們的數字或字母組合的數字(在本例中為 a、b、c 和 d、e、f)。也禁止使用動態記憶體(malloc、free)和帶有演算法的函式(qsort、lsearch 等)。檔案中的資訊格式為“name\n number\n name\n number\n...”。回圈無法正常作業,但我找不到錯誤。該程式應該回傳{Name}, {number},但它只回傳數字。代碼是:
`
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#define FULFILLED 1
#define NOT_FULFILLED 0
int main(int argc, char **argv)
{
char line[99];
int line_no = -1;
int size = strlen(argv[1]);
char letters[size][5];
int total_combinations = 1;
char combinations[total_combinations][size 1];
int current_combination[size];
int check_name = NOT_FULFILLED;
char name[99];
for(int i = 0; argv[1][i]; i )
{
switch(argv[1][i]) //cases according to input
{
case '0':
strcpy(letters[i], " ");
break;
case '2':
strcpy(letters[i], "abc");
break;
case '3':
strcpy(letters[i], "def");
break;
case '4':
strcpy(letters[i], "ghi");
break;
case '5':
strcpy(letters[i], "jkl");
break;
case '6':
strcpy(letters[i], "mno");
break;
case '7':
strcpy(letters[i], "pqrs");
break;
case '8':
strcpy(letters[i], "tuv");
break;
case '9':
strcpy(letters[i], "wxyz");
break;
}
total_combinations *= strlen(letters[i]); //number of combinations of letters from array elements
}
for (int i = 0; i < size; i )
{
current_combination[i] = 0;
}
int k = 0;
while (k < total_combinations)
{
for (int set_idx = 0; set_idx < size; set_idx )
{
int letter_idx = current_combination[set_idx];
combinations[k][set_idx] = letters[set_idx][letter_idx];
}
combinations[k][size] = '\0';
for(int i = size - 1; i >= 0; i--)
{
current_combination[i] ;
if (current_combination[i] == strlen(letters[i]))
{
current_combination[i] = 0;
}
else
{
break;
}
}
k ;
}
printf("%c\n", sizeof(combinations)/sizeof(combinations[0]));
while(fgets(line, sizeof(line), stdin))
{
line_no ;
if (line_no % 2 == 0) //even lines (names)
{
name[99] = line; //variable to use name with number
for (int i = 0; i < total_combinations; i ) //for each combination from array with combinations
{
if (strstr(line, combinations[i])) //if combination is a substring of a string
{
check_name = FULFILLED;
}
}
}
else if (line_no % 2 == 1) //odd lines (numbers)
{
if (check_name == FULFILLED || strstr(line, argv[1])) // if there's name that corresponds with input OR input is a substring of a string
{
printf("%s, %s", name, line);
check_name = NOT_FULFILLED;
}
}
}
}
`
我試圖改變檢查名稱的方式:
if (line_no % 2 == 0)
{
for (int j = 0; j <= strlen(letters); j )
{
char let = getchar();
for (int i = 0; i < strlen(line); i )
{
if (letters[j] == line[i])
{
check_name = FULFILLED;
continue;
}
else if (letters[j] != line [i])
{
break;
}
}
}
}
當然我沒有成功。因此,我將非常感謝任何幫助。
uj5u.com熱心網友回復:
當用于創建陣列的變數發生變化時,陣列不會反射性地調整大小。它們在初始化時永久調整大小。以下
int total_combinations = 1;
char combinations[total_combinations][size 1];
/* ... */
total_combinations *= strlen(letters[i]);
不會導致combinations增長total_combinations。將定義移至combinations完全total_combinations計算后。
以下嘗試將 a 分配char *給 a char,并且索引name超出范圍。
name[99] = line;
如前所述,用于strcpy復制字串。
請注意,如果找到并且緩沖區中有空間,fgets則將換行符存盤在緩沖區中,因此
printf("%s, %s", name, line);
很可能會列印交錯的輸出,例如
Alice
, 5551234567
粗略的重構:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
char *remove_newline(char *string)
{
if (string)
string[strcspn(string, "\n")] = '\0';
return string;
}
int main(int argc, char **argv)
{
if (argc < 2) {
fprintf(stderr, "usage: %s t9_sequence\n", argv[0]);
return EXIT_FAILURE;
}
int size = strlen(argv[1]);
char letters[size][5];
int total_combinations = 1;
int current_combination[size];
for (int i = 0; argv[1][i]; i ) {
switch (argv[1][i]) {
default:
fprintf(stderr, "Invalid input: \"%c\"\n", argv[1][i]);
return EXIT_FAILURE;
case '0':
strcpy(letters[i], " ");
break;
case '2':
strcpy(letters[i], "abc");
break;
case '3':
strcpy(letters[i], "def");
break;
case '4':
strcpy(letters[i], "ghi");
break;
case '5':
strcpy(letters[i], "jkl");
break;
case '6':
strcpy(letters[i], "mno");
break;
case '7':
strcpy(letters[i], "pqrs");
break;
case '8':
strcpy(letters[i], "tuv");
break;
case '9':
strcpy(letters[i], "wxyz");
break;
}
total_combinations *= strlen(letters[i]);
}
memset(current_combination, 0, sizeof current_combination);
char combinations[total_combinations][size 1];
for (int k = 0; k < total_combinations; k ) {
for (int set_idx = 0; set_idx < size; set_idx ) {
int letter_idx = current_combination[set_idx];
combinations[k][set_idx] = letters[set_idx][letter_idx];
}
combinations[k][size] = '\0';
for (int i = size - 1; i >= 0; i--) {
current_combination[i] ;
if (current_combination[i] != strlen(letters[i]))
break;
current_combination[i] = 0;
}
}
char name[128];
char number[128];
while (1) {
if (!fgets(name, sizeof name, stdin))
break;
if (!fgets(number, sizeof number, stdin))
break;
int found = 0;
for (int i = 0; i < total_combinations; i ) {
if (strstr(name, combinations[i])) {
found = 1;
break;
}
}
if (found || strstr(number, argv[1]))
printf("%s, %s\n", remove_newline(name), remove_newline(number));
}
}
轉載請註明出處,本文鏈接:https://www.uj5u.com/qukuanlian/523652.html
標籤:C
