我有以下方法读取两个字符串以更改数据库中两个条目的名字和姓氏。名称始终转换为小写,并且只应使用带有字母或连字符的名称,除非连字符是字符串中的第一个或最后一个字符。如果出现错误,它只会再次提示用户。
/*
Prompts for a student name, and checks if input is correct.
Returns 0 on success, -1 onEOF.
If the user inputs an invalid entry, the error is ignored and the user is simply asked again.
*/
int get_name(char *first, char *last)
{
char input[LINESIZE];
char buffer[LINESIZE];
char buffer2[LINESIZE];
int i;
while (1)
{
printf("\n%s", "Enter the Student Name ");
if (!fgets(input, LINESIZE, stdin))
{
clearerr(stdin);
return -1;
}
if (sscanf(input, "%s %s", buffer, buffer2) == 2)
{
if (strlen(buffer) < 20 && strlen(buffer2) < 20 && strlen(buffer) >= 2 && strlen(buffer2) >= 2) /*checks to see if the length is at least 2, but less than 20*/
{
for (i = 0; i < 20; i++) /*checks every character on the string, converts it to lower and then checks if it's a letter or a hyphen, restarts if not.*/
{
if (isalpha(buffer[i]))
{
buffer[i] = tolower(buffer[i]);
}
if (isalpha(buffer2[i]))
{
buffer2[i] = tolower(buffer2[i]);
}
if (!isalpha(buffer[i]) && buffer[i] != '-')
{
break;
}
if (!isalpha(buffer2[i]) && buffer2[i] != '-')
{
break;
}
}
if (buffer[0] == '-' || buffer[(strlen(buffer) - 1)] == '-')
{
i = 0;
}
if (buffer2[0] == '-' || buffer2[(strlen(buffer2) - 1)] == '-')
{
i = 0;
}
if (i == 20)
{
sscanf(buffer, "%s", first);
sscanf(buffer2, "%s", last);
return 0;
}
}
}
}
}
我已将错误跟踪到(!isalpha(buffer[i]) && buffer[i] != '-')
的行,但我无法弄清楚该陈述错误的原因。
例如,成功的输入可以是“john smith”或“Hom-er simpson”。在这两种情况下,函数都应返回0(成功)。 如果输入类似于:“Denny's White”,“-alexa redfield”,“albert”或“1234 5647”,则该功能应该重新开始(再次提示用户)。 此刻,无论输入如何,功能都会重新开始。
答案 0 :(得分:1)
程序中的主逻辑错误是您在两个阵列上同时运行具有固定数量(20)迭代的for
循环即可。您应该为名字和姓氏数组运行两个单独的循环。此外,您应该仅为每个数组的strlen
运行这两个循环。请参阅以下示例:
for (i = 0; i < strlen(buffer); i++)
{
/* your existing stuff for the "buffer" */
}
for (i = 0; i < strlen(buffer1); i++)
{
/* your existing stuff for the "buffer1" */
}
答案 1 :(得分:0)
警告: VHS遇到了主要问题。但是,这也指出了代码中可以改进的结构性问题。几乎所有代码都是为每个数组重复的。
创建一个对数组进行操作的函数[可能]可以更容易地看到问题。
我已经重新编写了你的代码来添加这个[请原谅无偿的样式清理]:
#include <stdio.h>
#include <string.h>
#include <ctype.h>
#define LINESIZE 80
int
bufdo(char *buf)
{
int len;
int idx;
int chr;
int ret;
len = strlen(buf);
do {
// assume non-conforming
ret = -1;
// length too great
if (len >= 20)
break;
// length too small
if (len < 2)
break;
// begins with hyphen
if (buf[0] == '-')
break;
// ends with hyphen
if (buf[len - 1] == '-')
break;
// assume it will be okay
ret = len;
// convert to lowercase and check for bad chars
for (idx = 0; idx < len; ++idx) {
chr = buf[idx];
if (isalpha(chr)) {
chr = tolower(chr);
buf[idx] = chr;
continue;
}
// non-hyphen char in name
if (chr != '-') {
ret = -1;
break;
}
}
} while (0);
return ret;
}
int
get_name(char *first, char *last)
{
char input[LINESIZE];
char buffer[LINESIZE];
char buffer2[LINESIZE];
int len1;
int len2;
int ret;
ret = -1;
while (1) {
printf("\n%s", "Enter the Student Name ");
fflush(stdout);
if (!fgets(input, LINESIZE, stdin)) {
clearerr(stdin);
break;
}
if (sscanf(input, "%s %s", buffer, buffer2) != 2)
continue;
len1 = bufdo(buffer);
len2 = bufdo(buffer2);
if ((len1 > 0) && (len2 > 0)) {
strcpy(first,buffer);
strcpy(last,buffer2);
ret = 0;
break;
}
}
return ret;
}