提问人:user22532748 提问时间:11/15/2023 最后编辑:Craig Esteyuser22532748 更新时间:11/15/2023 访问量:50
在 Mac 终端中编译后,C 程序未给出预期结果
C programs not giving expected results after compiling in Mac terminal
问:
我有一个项目,在MacBook终端中编译了24个C文件,每个文件都包含自己的功能。我使用 ar rcs libLibrary_name.a * .o 为这些函数创建了一个库,使用 gcc -c * .c 编译了它们,然后使用命令 gcc -o strtester strtester.c -L. Library_name.a 运行了我的驱动程序 strtester。虽然代码不会崩溃,但其中三个函数不会在驱动程序中提供预期的输出,尽管示例代码在这些文件中按预期运行。只有 24 个函数的这三个函数不起作用,我不确定为什么这些函数没有专门编译。
#include "string_library.h"
#include <stdio.h>
#include <ctype.h>
int
all_letters(char *s)
{
if (is_empty(s) == 1) {
return 0;
}
char *temp = s;
int all_letters = 1;
//Loops through , returning 0 if we
//find a non-alphabetic character, or 1
//otherwise. Since words can have spaces between
//them, if the string is not empty we ignore
//spaces
while (*temp != '\0') {
if (isalpha(*temp) == 0 && (*temp) != ' ') {
all_letters = 0;
break;
}
++temp;
}
return all_letters;
}
以上内容在文件中工作正常,但在编译时,它说“Hello World”和“Hell0 World”都不包含所有字母。虽然从技术上讲两者都有空格,但代码的编写方式是,如果发现字符串不为空,它将检查所有字母并忽略空格(因此只有数字和特殊字符应该返回失败,这在 strtester 中不会发生)
#include "string_library.h"
#include <stdio.h>
int
is_empty(char *s)
{
// If the string is null, it's empty
if (s == NULL) {
return 1;
}
// Checks if there are any non-whitespace characters
while (*s != '\0') {
if (*s != ' ') {
return 0;
}
s++;
}
return 1;
}
在实现它的文件中工作正常,但在驱动程序中给出相反的结果(说像“ ”这样的空字符串不为空,像“Hello”这样的字符串是空的)
#include "string_library.h"
#include <stdio.h>
#include <stdlib.h>
void
rm_empties(char **words)
{
// Indexes to help us remove strings
int total_index = 0;
int current_index = 0;
// Loops through until we reach the null pointer
while (words[total_index] != NULL) {
// Checks if the current string is not empty
int empty = is_empty(words[total_index]);
if (empty == 0) {
// If it's not empty, we copy it into words
words[current_index] = words[total_index];
current_index++;
}
total_index++;
}
// Caps off the array with the null pointer
words[current_index] = NULL;
}
int
main()
{
puts("Test for rm_empties");
char *to_empty[] = { "Hello", "World", " ", " ", "Steph", NULL };
puts("Array before emptying:");
int i = 0;
while (to_empty[i] != NULL) {
printf("%s\n", to_empty[i]);
i++;
}
char **s = to_empty;
rm_empties(to_empty);
puts("Array after emptying:");
int j = 0;
while (s[j] != NULL) {
printf("%s\n", s[j]);
j++;
}
}
在实现它的文件中工作正常,但在驱动程序中完全擦除数组。例如,给定数组 : {“Hello”, “Goodbye”, “ ”, “ ”, “Yes”, NULL},它只是擦除所有元素,而不是留下 “Hello”、“Goodbye” 和 “Yes” (null 指针停留以限制数组,因此保留是可以的)
以下是此 strtester 中每个函数的测试:
All_Letters:
puts("Test for all letters");
char *all_test = "Hello";
char *all_test_2 = "Hell0";
int is_all_letters = all_letters(all_test);
if (is_all_letters == 1) {
printf("All characters in %s are letters\n\n", all_test);
}
else {
printf("All characters in %s are not letters\n\n", all_test);
}
int is_all_letters_2 = all_letters(all_test_2);
if (is_all_letters_2 == 1) {
printf("All characters in %s are letters\n\n", all_test_2);
}
else {
printf("All characters in %s are not letters\n\n", all_test_2);
}
is_empty:
puts("Test for is_empty");
int is_empty_1 = is_empty(" ");
printf("%d", is_empty_1);
if (is_empty_1 == 0) {
puts("The string " "is not empty");
}
else {
puts("The string " " " " is empty");
}
int is_empty_2 = is_empty("Hello");
if (is_empty_2 == 0) {
puts("The string Hello is not empty");
}
else {
puts("The string Hello is empty");
}
Rm_empties:
puts("Test for rm_empties");
char *to_empty[] = { "Hello", "World", " ", " ", "Steph", NULL };
puts("Array before emptying:");
int i = 0;
while (to_empty[i] != NULL) {
printf("%s\n", to_empty[i]);
i++;
}
char **s = to_empty;
rm_empties(to_empty);
puts("Array after emptying:");
int j = 0;
while (s[j] != NULL) {
printf("%s\n", s[j]);
j++;
}
感谢您的帮助!
答:
我不确定为什么这些没有专门编译。
他们已经成功编译。你所描述的不是编译错误,而是逻辑错误或错误。
我对您的代码进行了一些修改,用于代替手动检查,用断言替换了大多数调用,并且无法重现您描述的问题。我没有看到您的驱动程序代码有什么特别的问题,也没有看到函数本身有什么特别的问题,所以问题出在别处。isspace()
printf()
#include <stdio.h>
#include <stdlib.h>
#include <ctype.h>
#include <assert.h>
#include <stdbool.h>
static bool is_empty(const char *s)
{
if (!s) {
return true;
}
while (*s) {
if (!isspace(*(unsigned char *)s)) {
return false;
}
++s;
}
return true;
}
static void rm_empties(const char **words)
{
size_t total_index = 0;
size_t current_index = 0;
while (words[total_index]) {
bool empty = is_empty(words[total_index]);
if (!empty) {
words[current_index] = words[total_index];
++current_index;
}
++total_index;
}
words[current_index] = NULL;
}
static bool is_all_letters(const char *s)
{
if (is_empty(s)) {
return 0;
}
while (*s) {
if(!isalpha(*(unsigned char *)s) && !isspace(*(unsigned char *)s)) {
return false;
}
++s;
}
return true;
}
int main(void)
{
assert(is_empty(""));
assert(!is_empty("a"));
assert(!is_empty("Hello"));
assert(is_all_letters("bigbang"));
assert(!is_all_letters("49ckancas#($"));
assert(!is_all_letters(" "));
assert(!is_all_letters("Hell0"));
const char *sample[] = {"Hello", "World", " ", "", "Steph", NULL};
size_t i = 0;
puts("BEFORE: ");
while(sample[i]) {
puts(sample[i]);
++i;
}
rm_empties(sample);
i = 0;
puts("AFTER: ");
while(sample[i]) {
puts(sample[i]);
++i;
}
return EXIT_SUCCESS;
}
输出:
$ ./str.exe
BEFORE:
Hello
World
Steph
AFTER:
Hello
World
Steph
评论
gcc -c * .c
编译了它们吗?