How to transfer result gotten from a function to an array of char in C? -
the motive of program test longest word in string , return whether or not longest word matches expected result.
i wrote code brain got stuck in part i'm store result of function longest word on line char array result. how do in c?
my effort:
#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 on lazy dogs", "jumped"); testlongestword("hello world said", "hello"); testlongestword("hello\tworld\tshe\tsaid", "hello"); testlongestword("hello, world said", "hello"); testlongestword("hello world! said???", "hello"); testlongestword("\"hello world!\", said.", "hello"); testlongestword("easy abc123", "abc123"); testlongestword("easy 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 b cc dd abc", "abc"); testlongestword("\"a b cc dd abc.\"", "abc"); printf("\n%s\n", "testing apostrophes , dashes\n" ); testlongestword("this isn't 5 chars", "chars"); testlongestword("this should've been 8 chars said computer", "should've"); testlongestword("'this should've been 8 chars', said computer", "should've"); testlongestword("'hello world!', said softly.", "softly"); testlongestword("topsy-turvy tenletter word", "topsy-turvy"); testlongestword("topsy-turvy should not incorrectly eleven characters", "incorrectly"); testlongestword("---in-between-these---", "in-between-these"); testlongestword("---in---between---these---", "between"); testlongestword("here-is-an-edge-case muchmuchlongerword", "muchmuchlongerword"); testlongestword("d-o-n't-g-o-o-v-e-r-t-h-e-e-d-g-e muchmuchlongerwords", "muchmuchlongerwords"); testlongestword("two=five-3 isn't three", "three"); printf("\n%s\n", "these tests opposite in c version\n"); testlongestword("the word antidisestablishmentarianism long not long 'llanfairpwllgwyngyllgogerychwyrndrobwyll-llantysiliogogogoch'.", "llanfairpwllgwyngyllgogerychwyrndrobwyll-llantysiliogogogoch"); testlongestword("the word antidisestablishmentarianism long not long 'llanfairpwllgwyngyllgogerychwyrndrobwyll-llantysiliogogogoch'.", "antidisestablishment"); testlongestword("java strings may contain \0 in interior", "interior"); testlongestword("c strings cannot contain \0 in 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 interior"); } char testlongestword(char line[], char expected[]){ //char result[200]; string result = longestwords(line); //this 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 equal printf("passed: '%s' '%s'\n", result, line); }else{ printf("failed: '%s' '%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; } } } }
output: (this output given in similar code done in java)
testing typical cases, including punctuation passed: 'jumped' 'the quick brown foxes jumped on lazy dogs' passed: 'hello' 'hello world said' passed: 'hello' 'hello world said' passed: 'hello' 'hello, world said' passed: 'hello' 'hello world! said???' passed: 'hello' '"hello world!", said.' passed: 'abc123' 'easy abc123' passed: 'easy' 'easy abc,123' testing empty cases passed: '' '' passed: '' '!' passed: '' ' ' passed: '' ' ' passed: '' ' ' passed: '' '# $ ? % !' testing edge cases passed: 'a' 'a' passed: 'abc' 'abc' passed: 'abc' 'abc d e f ghi' passed: 'abc' 'a b cc dd abc' passed: 'abc' '"a b cc dd abc."' testing apostrophes , dashes passed: 'chars' 'this isn't 5 chars' passed: 'should've' 'this should've been 8 chars said computer' passed: 'should've' ''this should've been 8 chars', said computer' passed: 'softly' ''hello world!', said softly.' passed: 'topsy-turvy' 'topsy-turvy tenletter word' passed: 'incorrectly' 'topsy-turvy should not incorrectly eleven characters' passed: 'in-between-these' '---in-between-these---' passed: 'between' '---in---between---these---' passed: 'muchmuchlongerword' 'here-is-an-edge-case muchmuchlongerword' passed: 'muchmuchlongerwords' 'd-o-n't-g-o-o-v-e-r-t-h-e-e-d-g-e muchmuchlongerwords' passed: 'three' 'two=five-3 isn't three' these tests opposite in c version passed: 'llanfairpwllgwyngyllgogerychwyrndrobwyll-llantysiliogogogoch' 'the word antidisestablishmentarianism long not long 'llanfairpwllgwyngyllgogerychwyrndrobwyll-llantysiliogogogoch'.' failed: 'llanfairpwllgwyngyllgogerychwyrndrobwyll-llantysiliogogogoch' instead of 'antidisestablishment' 'the word antidisestablishmentarianism long not long 'llanfairpwllgwyngyllgogerychwyrndrobwyll-llantysiliogogogoch'.' passed: 'interior' 'java strings may contain in interior' failed: 'interior' instead of 'strings' 'c strings cannot contain in interior' total number of tests executed: 34 number of tests passed: 32 number of tests failed: 2
your code had few problems. sense on final strcmp
if reversed. word finding logic bit convoluted, advancing pos
multiple times [incorrectly], , mechanism returning strings (ala java) didn't work. 1 simplification split off of longestword
code nextword
i've fixed code annotations [please pardon gratuitous style cleanup]:
#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 on lazy dogs", "jumped"); testlongestword("hello world said", "hello"); testlongestword("hello\tworld\tshe\tsaid", "hello"); testlongestword("hello, world said", "hello"); testlongestword("hello world! said???", "hello"); testlongestword("\"hello world!\", said.", "hello"); testlongestword("easy abc123", "abc123"); testlongestword("easy 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 b cc dd abc", "abc"); testlongestword("\"a b cc dd abc.\"", "abc"); printf("\n%s\n", "testing apostrophes , dashes\n"); testlongestword("this isn't 5 chars", "chars"); testlongestword("this should've been 8 chars said computer", "should've"); testlongestword("'this should've been 8 chars', said computer", "should've"); testlongestword("'hello world!', said softly.", "softly"); testlongestword("topsy-turvy tenletter word", "topsy-turvy"); testlongestword("topsy-turvy should not incorrectly eleven characters", "incorrectly"); testlongestword("---in-between-these---", "in-between-these"); testlongestword("---in---between---these---", "between"); testlongestword("here-is-an-edge-case muchmuchlongerword", "muchmuchlongerword"); testlongestword("d-o-n't-g-o-o-v-e-r-t-h-e-e-d-g-e muchmuchlongerwords", "muchmuchlongerwords"); testlongestword("two=five-3 isn't three", "three"); printf("\n%s\n", "these tests opposite in c version\n"); testlongestword("the word antidisestablishmentarianism long not long 'llanfairpwllgwyngyllgogerychwyrndrobwyll-llantysiliogogogoch'.", "llanfairpwllgwyngyllgogerychwyrndrobwyll-llantysiliogogogoch"); testlongestword("the word antidisestablishmentarianism long not long 'llanfairpwllgwyngyllgogerychwyrndrobwyll-llantysiliogogogoch'.", "antidisestablishment"); testlongestword("java strings may contain \0 in interior", "interior"); testlongestword("c strings cannot contain \0 in 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 interior"); } // nextword -- 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; (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 contraction] *lhs++ = ch; continue; break; case '-': // store hyphen *lhs++ = ch; continue; break; } } // didn't word char -- stop because we're @ end of 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) { // next word in line [we advance line pointer next round] line = nextword(current,line); if (line == null) break; // string length -- punctuation _not_ counted in string length currentlength = 0; (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 on dash strcpy(longest,current); } } char testlongestword(char *line,char *expected) { char result[2000]; //char result = longestwords(line); // 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 equal // note/bug: sense of if wrong if (strcmp(result, expected) == 0) { printf("passed: '%s' '%s'\n", result, line); } else { printf("failed: got '%s' '%s' -- expected '%s'\n", result, line, expected); testsfailed++; } testsexecuted++; return 0; }
update:
per request, belowed fully annotated version, explaining variable definitions , annotating control flow.
as doing this, realized nextword
computing [had knowledge] of things longestword
had recalculate, because nextword
had no way convey information.
so, i've added nextword
struct allows nextword
pass multiple values. don't know whether done in java, it's common in c.
the alternative return multiple values like:
nextword(blah,&var1,&var2,&var3,...);
this gets unwieldy quickly, decided opt cleaner approach, if it's more difficult understand @ first.
actually, way think of nextword
[java] class, single method nextword
. in context, i'd reverse order of nextword
arguments (e.g. nextword(&rtn,current)
) convention in c object instance pointer first argument.
#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 on lazy dogs", "jumped"); testlongestword("hello world said", "hello"); testlongestword("hello\tworld\tshe\tsaid", "hello"); testlongestword("hello, world said", "hello"); testlongestword("hello world! said???", "hello"); testlongestword("\"hello world!\", said.", "hello"); testlongestword("easy abc123", "abc123"); testlongestword("easy 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 b cc dd abc", "abc"); testlongestword("\"a b cc dd abc.\"", "abc"); printf("\n%s\n", "testing apostrophes , dashes\n"); testlongestword("this isn't 5 chars", "chars"); testlongestword("this should've been 8 chars said computer", "should've"); testlongestword("'this should've been 8 chars', said computer", "should've"); testlongestword("'hello world!', said softly.", "softly"); testlongestword("topsy-turvy tenletter word", "topsy-turvy"); testlongestword("topsy-turvy should not incorrectly eleven characters", "incorrectly"); testlongestword("---in-between-these---", "in-between-these"); testlongestword("---in---between---these---", "between"); testlongestword("here-is-an-edge-case muchmuchlongerword", "muchmuchlongerword"); testlongestword("d-o-n't-g-o-o-v-e-r-t-h-e-e-d-g-e muchmuchlongerwords", "muchmuchlongerwords"); testlongestword("two=five-3 isn't three", "three"); printf("\n%s\n", "these tests opposite in c version\n"); testlongestword("the word antidisestablishmentarianism long not long 'llanfairpwllgwyngyllgogerychwyrndrobwyll-llantysiliogogogoch'.", "llanfairpwllgwyngyllgogerychwyrndrobwyll-llantysiliogogogoch"); testlongestword("the word antidisestablishmentarianism long not long 'llanfairpwllgwyngyllgogerychwyrndrobwyll-llantysiliogogogoch'.", "antidisestablishment"); testlongestword("java strings may contain \0 in interior", "interior"); testlongestword("c strings cannot contain \0 in 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 interior"); } // nextword state control ("helper") // note: use sort of struct when must maintain/update _multiple_ // variables across function call [or calls] struct nextword { char *line; // current line position [updated] int alfcnt; // alphanumeric length int hypflg; // 1=word hyphenated }; // nextword -- next word void nextword(char *word,struct nextword *rtn) // word -- pointer place store extracted word // rtn -- pointer our state control , values return { char *line; // pointer sentence/phrase extract words char *wp; // current position in word int ch; // current character int c2; // next character [lookahead if needed] int alf1; // 1=current char alphanumeric int alf2; // 1=next char alphanumeric int alfcnt; // number of alphanumeric characters // printf("nextword: enter line='%s'\n",line); // no alpha chars , "not hyphenated" alfcnt = 0; rtn->hypflg = 0; // set word "creeper" [current position destination] // notes: // (1) using separate "wp" in unnecessary don't need retain // original word value (i.e. below "word" in place of // "wp") // (2) in previous version, called "lhs" [which, // surmised, meant "left hand side"] // (3) in style, might called "dst" [for destination] wp = word; // "source" pointer // notes: // (1) in style, named "rhs" ["right hand side"] // (2) style "src" "source" if used "dst" above line = rtn->line; (ch = *line; ch != 0; ch = *++line) { // current char alphanumeric? alf1 = isalpha(ch) || isdigit(ch); // store word chars // note: these characters considered our purposes of // "string" length if (alf1) { *wp++ = ch; alfcnt += 1; continue; } // iff we've started word, consider internal punctuation , // hyphenation if (alfcnt) { // peek @ _next_ character in line c2 = line[1]; alf2 = isalpha(c2) || isdigit(c2); // consider special characters if _next_ character alpha if (alf2) { switch (ch) { case '\'': // store quote [if it's part of contraction] *wp++ = ch; continue; break; case '-': // store hyphen *wp++ = ch; rtn->hypflg = 1; // remember word hyphenated continue; break; } } // didn't word char -- stop because we're @ end of word break; } // wait start of word (i.e. alphanumeric) } // finish off extracted word *wp = 0; // if didn't find word chars, tell caller stop if (! alfcnt) line = null; // return multiple values caller // note: 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 line void longestword(char *longest,char *line) // longest -- pointer buffer return longest extracted word // line -- pointer string has phrase extract words { int longlen = 0; // length of longest string far int longhyp = 0; // 1=longest word hyphenated char current[300]; // current word being considered int curlen; struct nextword rtn; // control struct allow nextword update state // handle empty strings longest[0] = 0; // initialize once -- nextword update rtn.line = line; while (1) { // next word in line [we advance line pointer next round] nextword(current,&rtn); // no more words found if (rtn.line == null) break; // nextword has computed length curlen = rtn.alfcnt; // store longer word [remembering length , whether it's // hyphenated or not] if (curlen > longlen) { strcpy(longest,current); longlen = curlen; longhyp = rtn.hypflg; continue; } // skip shorter words have if (curlen < longlen) continue; // decide if longest hyphenated -- ignore if not if (! longhyp) continue; // decide if current hyphenated -- ignore if (i.e. it's no better) if (rtn.hypflg) continue; // prefer non-dash on dash strcpy(longest,current); longhyp = rtn.hypflg; } } char testlongestword(char *line,char *expected) { char result[2000]; // char result = longestwords(line); // 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 equal // note/bug: sense of if wrong if (strcmp(result,expected) == 0) { printf("passed: '%s' '%s'\n",result,line); } else { printf("failed: got '%s' '%s' -- expected '%s'\n", result,line,expected); testsfailed++; } testsexecuted++; return 0; }
Comments
Post a Comment