gpt4 book ai didi

c - 如何将从函数获得的结果传输到 C 中的 char 数组?

转载 作者:太空宇宙 更新时间:2023-11-04 02:37:49 26 4
gpt4 key购买 nike

我的程序的动机是测试字符串中最长的单词并返回最长的单词是否与预期结果匹配。

我编写了代码,但我的大脑卡在了将函数最长单词的结果存储到 char 数组结果的部分。你如何在 C 中做到这一点?

我的努力:

#include <stdio.h>
#include <ctype.h>
#include <string.h>

static int testsExecuted = 0;
static int testsFailed = 0;

char testLongestWord(char line[], char expected[]);
void longestWord(char line[]);

int main(int args, char *argv[]){
printf("%s\n", "Testing typical cases, including punctuation\n");
testLongestWord("the quick brown foxes jumped over the lazy dogs", "jumped");
testLongestWord("hello world she said", "hello");
testLongestWord("Hello\tworld\tshe\tsaid", "Hello");
testLongestWord("HELLO, world she said", "HELLO");
testLongestWord("hello world! she said???", "hello");
testLongestWord("\"hello world!\", she said.", "hello");
testLongestWord("easy as abc123", "abc123");
testLongestWord("easy as abc,123", "easy");


printf("\n%s\n", "Testing empty cases\n" );
testLongestWord("", "");
testLongestWord("!", "");
testLongestWord(" ", "");
testLongestWord("\t", "");
testLongestWord(" ", "");
testLongestWord("# $ ? % !", "");

printf("\n%s\n", "Testing edge cases\n" );
testLongestWord("a", "a");
testLongestWord("abc", "abc");
testLongestWord("abc d e f ghi", "abc");
testLongestWord("a a b cc dd abc", "abc");
testLongestWord("\"a a b cc dd abc.\"", "abc");


printf("\n%s\n", "Testing apostrophes and dashes\n" );
testLongestWord("this isn't five chars", "chars");
testLongestWord("this should've been eight chars said the computer", "should've");
testLongestWord("'this should've been eight chars', said the computer", "should've");
testLongestWord("'hello world!', she said softly.", "softly");
testLongestWord("topsy-turvy is a tenletter word", "topsy-turvy");
testLongestWord("topsy-turvy should not be incorrectly eleven characters", "incorrectly");
testLongestWord("---in-between-these---", "in-between-these");
testLongestWord("---in---between---these---", "between");
testLongestWord("here-is-an-edge-case but a muchmuchlongerword", "muchmuchlongerword");
testLongestWord("d-o-n't-g-o-o-v-e-r-t-h-e-e-d-g-e with muchmuchlongerwords", "muchmuchlongerwords");
testLongestWord("two=five-3 isn't three", "three");

printf("\n%s\n", "These tests will be opposite in the C version\n");
testLongestWord("the word antidisestablishmentarianism is very long but not as long as 'Llanfairpwllgwyngyllgogerychwyrndrobwyll-llantysiliogogogoch'.", "Llanfairpwllgwyngyllgogerychwyrndrobwyll-llantysiliogogogoch");
testLongestWord("the word antidisestablishmentarianism is very long but not as long as 'Llanfairpwllgwyngyllgogerychwyrndrobwyll-llantysiliogogogoch'.", "antidisestablishment");
testLongestWord("Java strings may contain \0 in the interior", "interior");
testLongestWord("C strings cannot contain \0 in the interior", "strings");

printf("Total number of test executed: %d\n", testsExecuted );
printf("number of test passed: %d\n", (testsExecuted - testsFailed));
printf("Number of test failed: %d\n", testsFailed );

//longestWord("Java strings may contain \0 in the interior");

}

char testLongestWord(char line[], char expected[]){
//char result[200];
String result = longestWords(line); //This is how it'd have been in Java
/*longestWord(line);*/
//strcpy(result, line);
//char *result = longestWord(line);
//printf("%s\n", line );
//longestWord(&line)

if(strcmp(result,expected)){ // function returns 0 if they are equal
printf("passed: '%s' from '%s'\n", result, line);
}else{
printf("FAILED: '%s' from '%s'\n", expected, result);
testsFailed++;
}
testsExecuted++;
return 0;

}


void longestWord(char line[]){
char longest[200];

int pos = 0;
int longestLength = 0;
char current[300];
int currentLength = 0;
char ch;
size_t maxPos = strlen(line);

while(pos < maxPos){
ch = line[pos++];
for(pos = 0; pos < maxPos;pos++){
ch = line[pos++];
if((ch == '\'' || ch == '-') && (pos > 0) && isalpha(line[pos-1]) && isalpha(line[pos+1])){
strcpy(current, &ch);
}else if(isalpha(ch) || isdigit(ch)){
strcpy(current, &ch);
currentLength++;
//printf("%s\n", longest );

}else{
if(currentLength > longestLength){
strcpy(longest,current);
longestLength = currentLength;
}
//strcpy(current, "");
currentLength =0;
}
}

}

}

输出:(此输出是在刚刚用 Java 完成的类似代码中给出的)

Testing typical cases, including punctuation

Passed: 'jumped' from 'the quick brown foxes jumped over the lazy dogs'
Passed: 'hello' from 'hello world she said'
Passed: 'Hello' from 'Hello world she said'
Passed: 'HELLO' from 'HELLO, world she said'
Passed: 'hello' from 'hello world! she said???'
Passed: 'hello' from '"hello world!", she said.'
Passed: 'abc123' from 'easy as abc123'
Passed: 'easy' from 'easy as abc,123'

Testing empty cases

Passed: '' from ''
Passed: '' from '!'
Passed: '' from ' '
Passed: '' from ' '
Passed: '' from ' '
Passed: '' from '# $ ? % !'

Testing edge cases

Passed: 'a' from 'a'
Passed: 'abc' from 'abc'
Passed: 'abc' from 'abc d e f ghi'
Passed: 'abc' from 'a a b cc dd abc'
Passed: 'abc' from '"a a b cc dd abc."'

Testing apostrophes and dashes

Passed: 'chars' from 'this isn't five chars'
Passed: 'should've' from 'this should've been eight chars said the computer'
Passed: 'should've' from ''this should've been eight chars', said the computer'
Passed: 'softly' from ''hello world!', she said softly.'
Passed: 'topsy-turvy' from 'topsy-turvy is a tenletter word'
Passed: 'incorrectly' from 'topsy-turvy should not be incorrectly eleven characters'
Passed: 'in-between-these' from '---in-between-these---'
Passed: 'between' from '---in---between---these---'
Passed: 'muchmuchlongerword' from 'here-is-an-edge-case but a muchmuchlongerword'
Passed: 'muchmuchlongerwords' from 'd-o-n't-g-o-o-v-e-r-t-h-e-e-d-g-e with muchmuchlongerwords'
Passed: 'three' from 'two=five-3 isn't three'

These tests will be opposite in the C version

Passed: 'Llanfairpwllgwyngyllgogerychwyrndrobwyll-llantysiliogogogoch' from 'the word antidisestablishmentarianism is very long but not as long as 'Llanfairpwllgwyngyllgogerychwyrndrobwyll-llantysiliogogogoch'.'
FAILED: 'Llanfairpwllgwyngyllgogerychwyrndrobwyll-llantysiliogogogoch' instead of 'antidisestablishment' from 'the word antidisestablishmentarianism is very long but not as long as 'Llanfairpwllgwyngyllgogerychwyrndrobwyll-llantysiliogogogoch'.'
Passed: 'interior' from 'Java strings may contain in the interior'
FAILED: 'interior' instead of 'strings' from 'C strings cannot contain in the interior'

Total number of tests executed: 34
Number of tests passed: 32
Number of tests failed: 2

最佳答案

您的代码有一些问题。你最后的 strcmp if 的意义被颠倒了。单词查找逻辑有点复杂,多次推进 pos [不正确],并且返回字符串的机制(ala java)不起作用。一种简化是将一些 longestWord 代码拆分为 nextWord

我已经用一些注释修复了代码[请原谅不必要的样式清理]:

#include <stdio.h>
#include <ctype.h>
#include <string.h>

static int testsExecuted = 0;
static int testsFailed = 0;

char testLongestWord(char line[], char expected[]);
//void longestWord(char line[]);

int
main(int args, char *argv[])
{
printf("%s\n", "Testing typical cases, including punctuation\n");
testLongestWord("the quick brown foxes jumped over the lazy dogs", "jumped");
testLongestWord("hello world she said", "hello");
testLongestWord("Hello\tworld\tshe\tsaid", "Hello");
testLongestWord("HELLO, world she said", "HELLO");
testLongestWord("hello world! she said???", "hello");
testLongestWord("\"hello world!\", she said.", "hello");
testLongestWord("easy as abc123", "abc123");
testLongestWord("easy as abc,123", "easy");

printf("\n%s\n", "Testing empty cases\n");
testLongestWord("", "");
testLongestWord("!", "");
testLongestWord(" ", "");
testLongestWord("\t", "");
testLongestWord(" ", "");
testLongestWord("# $ ? % !", "");

printf("\n%s\n", "Testing edge cases\n");
testLongestWord("a", "a");
testLongestWord("abc", "abc");
testLongestWord("abc d e f ghi", "abc");
testLongestWord("a a b cc dd abc", "abc");
testLongestWord("\"a a b cc dd abc.\"", "abc");

printf("\n%s\n", "Testing apostrophes and dashes\n");
testLongestWord("this isn't five chars", "chars");
testLongestWord("this should've been eight chars said the computer", "should've");
testLongestWord("'this should've been eight chars', said the computer", "should've");
testLongestWord("'hello world!', she said softly.", "softly");
testLongestWord("topsy-turvy is a tenletter word", "topsy-turvy");
testLongestWord("topsy-turvy should not be incorrectly eleven characters", "incorrectly");
testLongestWord("---in-between-these---", "in-between-these");
testLongestWord("---in---between---these---", "between");
testLongestWord("here-is-an-edge-case but a muchmuchlongerword", "muchmuchlongerword");
testLongestWord("d-o-n't-g-o-o-v-e-r-t-h-e-e-d-g-e with muchmuchlongerwords", "muchmuchlongerwords");
testLongestWord("two=five-3 isn't three", "three");

printf("\n%s\n", "These tests will be opposite in the C version\n");
testLongestWord("the word antidisestablishmentarianism is very long but not as long as 'Llanfairpwllgwyngyllgogerychwyrndrobwyll-llantysiliogogogoch'.", "Llanfairpwllgwyngyllgogerychwyrndrobwyll-llantysiliogogogoch");
testLongestWord("the word antidisestablishmentarianism is very long but not as long as 'Llanfairpwllgwyngyllgogerychwyrndrobwyll-llantysiliogogogoch'.", "antidisestablishment");
testLongestWord("Java strings may contain \0 in the interior", "interior");
testLongestWord("C strings cannot contain \0 in the interior", "strings");

printf("Total number of test executed: %d\n", testsExecuted);
printf("number of test passed: %d\n", (testsExecuted - testsFailed));
printf("Number of test failed: %d\n", testsFailed);

// longestWord("Java strings may contain \0 in the interior");

}

// nextWord -- get next word
char *
nextWord(char *word,char *line)
{
char *lhs;
int c2;
int alfcnt;
int alf1;
int alf2;
int ch;

//printf("nextWord: ENTER line='%s'\n",line);

alfcnt = 0;
lhs = word;

for (ch = *line; ch != 0; ch = *++line) {
alf1 = isalpha(ch) || isdigit(ch);

// store word chars
if (alf1) {
*lhs++ = ch;
alfcnt = 1;
continue;
}

if (alfcnt) {
c2 = line[1];
alf2 = isalpha(c2) || isdigit(c2);

if (alf2) {
switch (ch) {
case '\'': // store single quote [if it's part of a contraction]
*lhs++ = ch;
continue;
break;

case '-': // store hyphen
*lhs++ = ch;
continue;
break;
}
}

// didn't get a word char -- stop because we're at the end of a word
break;
}
}

*lhs = 0;

if (! alfcnt)
line = NULL;

//printf("nextWord: EXIT lhs='%s' line='%s'\n",lhs,line);

return line;
}

void
longestWord(char *longest,char *line)
{
int longestLength = 0;
char current[300];
int currentLength = 0;
char *cp;

longest[0] = 0;

while (1) {
// get next word in line [we advance the line pointer for next round]
line = nextWord(current,line);
if (line == NULL)
break;

// get string length -- punctuation is _not_ counted in string length
currentLength = 0;
for (cp = current; *cp != 0; ++cp) {
switch (*cp) {
case '-':
case '\'':
break;
default:
currentLength += 1;
break;
}
}

// store longer word
if (currentLength > longestLength) {
strcpy(longest,current);
longestLength = currentLength;
continue;
}

if (currentLength < longestLength)
continue;

cp = strchr(longest,'-');
if (cp == NULL)
continue;

cp = strchr(current,'-');
if (cp != NULL)
continue;

// prefer non-dash over dash
strcpy(longest,current);
}
}

char
testLongestWord(char *line,char *expected)
{
char result[2000];
//char result = longestWords(line); // This is how it'd have been in Java

longestWord(result,line);

/* longestWord(line); */
// strcpy(result, line);
// char *result = longestWord(line);
// printf("%s\n", line );
// longestWord(&line)

// function returns 0 if they are equal
// NOTE/BUG: the sense of the if was wrong
if (strcmp(result, expected) == 0) {
printf("passed: '%s' from '%s'\n", result, line);
}
else {
printf("FAILED: got '%s' from '%s' -- expected '%s'\n",
result, line, expected);
testsFailed++;
}

testsExecuted++;

return 0;
}

更新:

根据您的要求,下面是一个完整注释版本,解释了变量定义并注释了控制流。

当我这样做时,我意识到 nextWord 正在计算 [had knowledge] longestWord 必须重新计算的东西,仅仅是因为 nextWord 无法传达此信息。

因此,我添加了一个 nextword 结构,它允许 nextWord 返回多个 值。我不知道这是否是用 java 完成的,但它在 C 中相当常见。

返回多个值的替代方法是执行如下操作:

nextWord(blah,&var1,&var2,&var3,...);

这很快就会变得笨拙,所以我决定选择更简洁的方法,即使一开始它有点难以理解。

实际上,另一种思考方式是 nextword 就像一个 [java] 类,只有一个方法 nextWord。在这种情况下,我可能会颠倒 nextWord 参数的顺序(例如 nextWord(&rtn,current)),因为我在 C 中的约定是对象实例指针是第一个参数。

#include <stdio.h>
#include <ctype.h>
#include <string.h>

static int testsExecuted = 0;
static int testsFailed = 0;

char testLongestWord(char line[],char expected[]);

//void longestWord(char line[]);

int
main(int args,char *argv[])
{
printf("%s\n", "Testing typical cases, including punctuation\n");
testLongestWord("the quick brown foxes jumped over the lazy dogs", "jumped");
testLongestWord("hello world she said", "hello");
testLongestWord("Hello\tworld\tshe\tsaid", "Hello");
testLongestWord("HELLO, world she said", "HELLO");
testLongestWord("hello world! she said???", "hello");
testLongestWord("\"hello world!\", she said.", "hello");
testLongestWord("easy as abc123", "abc123");
testLongestWord("easy as abc,123", "easy");

printf("\n%s\n", "Testing empty cases\n");
testLongestWord("", "");
testLongestWord("!", "");
testLongestWord(" ", "");
testLongestWord("\t", "");
testLongestWord(" ", "");
testLongestWord("# $ ? % !", "");

printf("\n%s\n", "Testing edge cases\n");
testLongestWord("a", "a");
testLongestWord("abc", "abc");
testLongestWord("abc d e f ghi", "abc");
testLongestWord("a a b cc dd abc", "abc");
testLongestWord("\"a a b cc dd abc.\"", "abc");

printf("\n%s\n", "Testing apostrophes and dashes\n");
testLongestWord("this isn't five chars", "chars");
testLongestWord("this should've been eight chars said the computer", "should've");
testLongestWord("'this should've been eight chars', said the computer", "should've");
testLongestWord("'hello world!', she said softly.", "softly");
testLongestWord("topsy-turvy is a tenletter word", "topsy-turvy");
testLongestWord("topsy-turvy should not be incorrectly eleven characters", "incorrectly");
testLongestWord("---in-between-these---", "in-between-these");
testLongestWord("---in---between---these---", "between");
testLongestWord("here-is-an-edge-case but a muchmuchlongerword", "muchmuchlongerword");
testLongestWord("d-o-n't-g-o-o-v-e-r-t-h-e-e-d-g-e with muchmuchlongerwords", "muchmuchlongerwords");
testLongestWord("two=five-3 isn't three", "three");

printf("\n%s\n", "These tests will be opposite in the C version\n");
testLongestWord("the word antidisestablishmentarianism is very long but not as long as 'Llanfairpwllgwyngyllgogerychwyrndrobwyll-llantysiliogogogoch'.", "Llanfairpwllgwyngyllgogerychwyrndrobwyll-llantysiliogogogoch");
testLongestWord("the word antidisestablishmentarianism is very long but not as long as 'Llanfairpwllgwyngyllgogerychwyrndrobwyll-llantysiliogogogoch'.", "antidisestablishment");
testLongestWord("Java strings may contain \0 in the interior", "interior");
testLongestWord("C strings cannot contain \0 in the interior", "strings");

printf("Total number of test executed: %d\n", testsExecuted);
printf("number of test passed: %d\n", (testsExecuted - testsFailed));
printf("Number of test failed: %d\n", testsFailed);

// longestWord("Java strings may contain \0 in the interior");

}

// nextWord state control ("helper")
// NOTE: we use this sort of struct when we must maintain/update _multiple_
// variables across a function call [or calls]
struct nextword {
char *line; // current line position [updated]
int alfcnt; // alphanumeric length
int hypflg; // 1=word is hyphenated
};

// nextWord -- get next word
void
nextWord(char *word,struct nextword *rtn)
// word -- pointer to place to store extracted word
// rtn -- pointer to our state control and values we return
{
char *line; // pointer to sentence/phrase to extract words from
char *wp; // current position in word
int ch; // current character
int c2; // next character [lookahead if needed]
int alf1; // 1=current char is alphanumeric
int alf2; // 1=next char is alphanumeric
int alfcnt; // number of alphanumeric characters

// printf("nextWord: ENTER line='%s'\n",line);

// say no alpha chars and "not hyphenated"
alfcnt = 0;
rtn->hypflg = 0;

// set the word "creeper" [current position for destination]
// NOTES:
// (1) using a separate "wp" in unnecessary as we don't need to retain the
// original word value (i.e. below we could just do "word" in place of
// "wp")
// (2) in the previous version, this was called "lhs" [which, as you
// surmised, meant "left hand side"]
// (3) in my style, this might also be called "dst" [for destination]
wp = word;

// get "source" pointer
// NOTES:
// (1) in my style, this could also be named "rhs" ["right hand side"]
// (2) another style would be "src" for "source" if we used "dst" above
line = rtn->line;

for (ch = *line; ch != 0; ch = *++line) {
// is current char alphanumeric?
alf1 = isalpha(ch) || isdigit(ch);

// store word chars
// NOTE: only these characters are considered for our purposes of
// "string" length
if (alf1) {
*wp++ = ch;
alfcnt += 1;
continue;
}

// iff we've started a word, we consider internal punctuation and
// hyphenation
if (alfcnt) {
// peek at _next_ character in line
c2 = line[1];
alf2 = isalpha(c2) || isdigit(c2);

// consider special characters if _next_ character is alpha
if (alf2) {
switch (ch) {
case '\'': // store quote [if it's part of a contraction]
*wp++ = ch;
continue;
break;

case '-': // store hyphen
*wp++ = ch;
rtn->hypflg = 1; // remember that word is hyphenated
continue;
break;
}
}

// didn't get a word char -- stop because we're at the end of a word
break;
}

// wait for start of a word (i.e. alphanumeric)
}

// finish off the extracted word
*wp = 0;

// if we didn't find any word chars, tell caller to stop
if (! alfcnt)
line = NULL;

// return multiple values to caller
// NOTE: we already updated hypflg above [if necessary]
rtn->alfcnt = alfcnt;
rtn->line = line;

// printf("nextWord: EXIT lhs='%s' line='%s'\n",lhs,line);
}

// longestWord -- find longest word in a line
void
longestWord(char *longest,char *line)
// longest -- pointer to buffer where we return the longest extracted word
// line -- pointer to string that has the phrase to extract words from
{
int longlen = 0; // length of longest string so far
int longhyp = 0; // 1=longest word is hyphenated
char current[300]; // current word being considered
int curlen;
struct nextword rtn; // control struct to allow nextWord to update state

// handle empty strings
longest[0] = 0;

// initialize this once -- nextWord will update it
rtn.line = line;

while (1) {
// get next word in line [we advance the line pointer for next round]
nextWord(current,&rtn);

// no more words found
if (rtn.line == NULL)
break;

// nextWord has already computed the length for us
curlen = rtn.alfcnt;

// store longer word [remembering its length and whether it's
// hyphenated or not]
if (curlen > longlen) {
strcpy(longest,current);
longlen = curlen;
longhyp = rtn.hypflg;
continue;
}

// skip shorter words than what we already have
if (curlen < longlen)
continue;

// decide if longest is hyphenated -- ignore if not
if (! longhyp)
continue;

// decide if current is hyphenated -- ignore if so (i.e. it's no better)
if (rtn.hypflg)
continue;

// prefer non-dash over dash
strcpy(longest,current);
longhyp = rtn.hypflg;
}
}

char
testLongestWord(char *line,char *expected)
{
char result[2000];

// char result = longestWords(line); // This is how it'd have been in Java

longestWord(result,line);

/* longestWord(line); */
// strcpy(result,line);
// char *result = longestWord(line);
// printf("%s\n",line );
// longestWord(&line)

// function returns 0 if they are equal
// NOTE/BUG: the sense of the if was wrong
if (strcmp(result,expected) == 0) {
printf("passed: '%s' from '%s'\n",result,line);
}
else {
printf("FAILED: got '%s' from '%s' -- expected '%s'\n",
result,line,expected);
testsFailed++;
}

testsExecuted++;

return 0;
}

关于c - 如何将从函数获得的结果传输到 C 中的 char 数组?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/35165509/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com