Reputation: 77
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);
}
Upvotes: 1
Views: 3665
Reputation: 8344
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";
// some compilers disallow modifying string literals
char *copy = malloc( strlen( src ) + 1 );
strcpy( copy, src );
printf( "%s", copy );
for( int i = 0; i < sizeof words/sizeof words[0]; i++ )
uc( copy, words[i] );
free( copy );
return 0;
}
I make no claim that this is complete. My hope is that you will be able to understand what is needed.
Output of final printf(): (added as 'proof' of functionality). Notice that return
, int
, void
and while
have been UPPERCASE'd.
**FOUND** 'while'
#include <stdio.h>
INT func( INT x ) {
RETURN (x * x);
}
INT main( VOID ) {
INT longval = 3;
WHILE( ( longval = func( longval ) ) < 10000 )
printf( "%d\n", longval );
RETURN 0;
}
Upvotes: 1
Reputation: 8944
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;
}
Edit: While I use int
in this example, size_t
is preferable to avoid the an integer overflow on large strings causing bytes to be accessed outside the bounds of the string (Effects strings with over 2,147,483,647 bytes on most systems depending on the compiler configuration. Strings under 32,768 bytes will not be effected regardless of compiler configuration).
Upvotes: 1