I'm trying to make all keywords from C into uppercase from a C file, but when I try to use the toupper function from stdlib it only accepts char type
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
const char *words[] = {
"auto", "break", "case", "char", "continue", "do", "default", "const","double", "else", "enum", "extern", "for", "if", "goto", "float", "int", "long", "register", "return", "signed", "static", "sizeof", "short", "struct","switch","typedef","union","void", "while","volatile", "unsigned"
};
int main()
{
char line[200];
size_t len = 0;
FILE *f;
f = fopen("main.c", "r");
int line_no = 0;
while (fgets(line, sizeof line, f))
{
line_no;
for (size_t i = 0; i < (sizeof words)/sizeof *words; i )
{
if (strstr(line, words[i]) != NULL && line_no > 8)
{
printf("%s", words[i]);
}
}
}
fclose(f);
}
CodePudding user response:
You need to convert the string one character at a time. Since string literals are stored in read-only memory, we need to allocate space for a new string and copy over the characters one by one. However, you will need to remember to free these after use. Alternatively, if we know all the strings are short, you could alternatively do this in an array on the stack.
char *toUppercase(char *lower) {
int len = strlen(lower);
// Allocate space for new string
char *upper = (char *) malloc(sizeof(char) * (len 1));
// Add null terminator to string
upper[len] = '\0';
// Convert characters to uppercase one by one
for (int i = 0; i < len; i ) {
upper[i] = toupper(lower[i]);
}
return upper;
}
CodePudding user response:
It's raining, and this challenge seemed interesting.
Here's a rough cut of what you might expand to suit your needs.
Instead of dealing with one line at a time (fgets), this simulates loading the entire file (fopen/ftell/fseek/fread) with a single long 'target' string.
It loops through each of the keywords, uppercase'ing when it encounters one. (You need to be careful... Notice the test that ensures "longval" is not made uppercase.)
Thanks for the fun!
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <ctype.h>
const char *words[] = {
"auto", "break", "case", "char", "continue", "do", "default", "const",
"double", "else", "enum", "extern", "for", "if", "goto", "float", "int",
"long", "register", "return", "signed", "static", "sizeof", "short",
"struct","switch","typedef","union", "void", "while", "volatile", "unsigned"
};
void uc( char *buf, const char *word ) {
int len = strlen( word ); // may need this...
bool found = false;
for( char *cp = buf; ( cp = strstr( cp, word ) ) != NULL; cp ) {
char c = cp[len]; // one char beyond keyword length
if( !isalpha( c ) && !isdigit( c ) && c != '_' ) {
found = true;
for( int i = 0; i < len; i )
cp[i] = (char)toupper( cp[i] );
}
}
if( found )
printf( "\n\n**FOUND** '%s'\n\n%s", word, buf );
}
int main() {
char *src =
"#include <stdio.h>\n\n"
"int func( int x ) {\n return (x * x);\n}\n\n"
"int main( void ) {\n"
" int longval = 3;\n"
" while( ( longval = func( longval ) ) < 10000 )\n"
" printf( \"%d\\n\", longval );\n"
" return 0;\n"
"}\n";
printf( "%s", src );
for( int i = 0; i < sizeof words/sizeof words[0]; i )
uc( src, words[i] );
return 0;
}
I make no claim that this is complete. My hope is that you will be able to understand what is needed.