I'm trying to convert a char * to uppercase in c, but the function toupper() doesn't work here.
I'm trying to get the name of the the value of temp, the name being anything before the colon, in this case it's "Test", and then I want to capitalize the name fully.
void func(char * temp) {
// where temp is a char * containing the string "Test:Case1"
char * name;
name = strtok(temp,":");
//convert it to uppercase
name = toupper(name); //error here
}
I'm getting the error that the function toupper() expects an int, but receives a char *. Thing is, I have to use char *s, since that is what the function is taking in, (I can't really use char arrays here, can I?).
Any help would be greatly appreciated.
toupper() converts a single char.
Simply use a loop:
void func(char * temp) {
char * name;
name = strtok(temp,":");
// Convert to upper case
char *s = name;
while (*s) {
*s = toupper((unsigned char) *s);
s++;
}
}
Detail: The standard Library function toupper(int) is defined for all unsigned char and EOF. Since char may be signed, convert to unsigned char.
Some OS's support a function call that does this: upstr() and strupr()
For those of you who want to uppercase a string and store it in a variable (that was what I was looking for when I read these answers).
#include <stdio.h> //<-- You need this to use printf.
#include <string.h> //<-- You need this to use string and strlen() function.
#include <ctype.h> //<-- You need this to use toupper() function.
int main(void)
{
string s = "I want to cast this"; //<-- Or you can ask to the user for a string.
unsigned long int s_len = strlen(s); //<-- getting the length of 's'.
//Defining an array of the same length as 's' to, temporarily, store the case change.
char s_up[s_len];
// Iterate over the source string (i.e. s) and cast the case changing.
for (int a = 0; a < s_len; a++)
{
// Storing the change: Use the temp array while casting to uppercase.
s_up[a] = toupper(s[a]);
}
// Assign the new array to your first variable name if you want to use the same as at the beginning
s = s_up;
printf("%s \n", s_up); //<-- If you want to see the change made.
}
Note: If you want to lowercase a string instead, change toupper(s[a]) to tolower(s[a]).
toupper() works only on a single character. But there is strupr() which is what you want for a pointer to a string.
How about this little function? It assumes ASCII represented chars and modifies string in place.
void to_upper(char* string)
{
const char OFFSET = 'a' - 'A';
while (*string)
{
*string = (*string >= 'a' && *string <= 'z') ? *string -= OFFSET : *string;
string++;
}
}
toupper() works on one element (int argument, value ranging the same as of unsigned char or EOF) at a time.
Prototype:
int toupper(int c);
You need to use a loop to supply one element at a time from your string.
Related
Is it possible to use one string function inside another string function. See below....
strcmp(string1, strupr(string2));
Here I have used strupr() function to make the all characters of string2 in uppercase then It will use to compare with string1 by strcmp() function.
Below is my program...
#include <stdio.h>
#include <string.h>
int main()
{
char str[41], name[43];
gets(str);
gets(name);
if (strcmp(strupr(str), name) == 0)
printf("\nwow it works.");
return 0;
}
Following is the error shown by compilor..
use of undeclared identifier 'strupr'; did you mean 'strdup'?
To condense the comments into an answer:
As long as the return type of the inner function matches (or is compatible with) the argument type of the outer function, this will work.
A simple example, which will print the number 3.
int add1(int a) {
return a + 1;
}
int main(void) {
printf("%d\n", add1(add1(add1(0))));
}
So as long as your strupr function returns a char * (or const char *, etc.) it will work as the function prototype for strcmp is:
int strcmp(const char *s1, const char *s2);
To create a basic function to uppercase an entire string, you simply loop through the string character by character and use the toupper function on each character. There are several ways to implement this loop.
Here is one such way:
char *upcase(char *s) {
for (char *p = s; p && *p; p++)
*p = toupper(*p);
return s;
}
Note that this is a destructive function, which alters the contents of the string passed to it. It will not work with static strings (e.g., const char *foo = "abcdefg";).
Since your aim seems to compare the two strings in a case insensitive fashion, you should use stricmp:
if (stricmp(str, name) == 0)
printf("\nwow it works.");
It has the additional benefits of not either changing your original string or allocating a new string you will have to free().
I'm trying to read a string from argv. It should be something like a mathematical function like "-x^2-5" etc.
I've got something like this:
void test(char *function){
int temp = 0;
for (int i = 0; i < strlen(function); i++){
if((function[i] != '+') && (function[i] != ...){
// function[i] is a digit, but still as a char
temp = atoi(function[i]);
}
}
//...
}
int main(int argc, char **argv){
test(argv[1]);
//...
}
This works quite well until the last lap of the loop.
If I use printf("%c", function[i]);, it sais, it's 5.
But atoi(function[i]) gives a segfault. Why?
Right. Let's first take a look at the signature of atoi.
int atoi(const char *str);
Now, what you are passing to it is function[i], and since function is of type char *, function[i] is a char. And your character is most likely not a proper character pointer.
What you'd want to pass to atoi is instead a const char *, which you can get by calling atoi(&function[i]);
As already said by #sham1, atoi expects its parameter to be a C string, this is a null terminated char array, while you have a single char.
But digits are special, because they are required to have consecutive codes. So if you know that a character (say c) is a digit, its value is c - '0'. So you can write:
if((function[i] != '+') && (function[i] != ...){
// function[i] is a digit, but still as a char
temp = function[i] - '0'; // get the int value of a digit character
}
Besides the bug pointed out in other answers, atoi doesn't have any reliable error handling, which is why it is one of the standard library functions that should never be used.
Just forget that you ever heard about atoi and replace it with:
char* endptr;
int result = strtol(str,&endptr,10);
if(endptr == str)
{
// some conversion error
}
strtol is also able to convert an initial part of the string if it contains valid numbers.
I am trying to make a function toLowerCase(char *string) but I am unable to make it work properly.
This is my code
void toLowerCase(char *string) {
int i = 0;
while (*(string+i) != '\0') {
if (*(string+i) >= 'A' && *(string+i) <= 'Z') {
*(string+i) = *(string+i) + 32;
}
i++;
}
printf("%s", string);
}
I am trying to loop through the string that is a char * pointer by accessing each element using *(string + i) and using ASCII to convert to Lowercase.
I am new here, if this was answered before I am sorry, but I am asking because I couldn't find a specific solution to my problem. I've tried what's in this thread: Converting Char * to Uppercase in C
but it didn't work for me either.
EDIT: This is how I call my function
int main() {
toLowerCase("HELLO WORLD");
return 0;
}
EDIT 2: So, I did this, as showed by PSkocik. And it worked, but I don't know why it works like this. Will the toLowerCase() function work with any char * pointer? even if I don't declare it as char array?
This also fixes the problem that Vlad from Moscow pointed out that I am using a string literal
#define T 100
int main() {
char string[T] = "HELLO WORLD";
toLowerCase(&string);
return 0;
}
EDIT 3: Thank you very much for your help! I wasn't expecting to get help so quickly! I didn't know what a string literal was!
Thank you very much for your time
C string literals are typed char[] for historical reasons, but they're effectively char const[]—you are not allowed to modify them.
Fortunately C makes it very easy to create a writable copy by letting you initialize a writable char array with a string literal:
#include <stdio.h>
void toLowerCase(char* string)
{
int i=0;
while(*(string+i)!= '\0'){
if (*(string+i) >= 'A' && *(string+i)<='Z'){
*(string+i)= *(string+i)+32;
}
i++;
}
}
int main()
{
char string[]="HELLO WORLD";
toLowerCase(&string[0]);
puts(string);
//prints: hello world
}
https://gcc.godbolt.org/z/X4YA5B
(*(string+i) instead of string[i] is slightly unusual and I'd at least replace the magic constant 32 with ('a'-'A'), but the callee's code is otherwise OK.)
You may not change string literals. Any attempt to change a string literal results in undefined behavior.
From the C Standard (6.4.5 String literals)
7 It is unspecified whether these arrays are distinct provided their
elements have the appropriate values. If the program attempts to
modify such an array, the behavior is undefined.
So instead of this call
toLowerCase("HELLO WORLD");
use at least
char s[] = "HELLO WORLD";
toLowerCase( s );
Pay attention to that it will be much better when the function will return pointer to the modified string and will not output the string. It is the caller of the function that will decide whether to output the modified string.
So define the function like
char * toLowerCase( char *string )
{
// ...
return string;
}
You are passing a string literal to the function toLowerCase and then trying to change it using *(string+i)= *(string+i)+32;.
You should contain Hello World in a variable and then pass it to the function if you want to change the case of characters.
toLowerCase("HELLO WORLD"); => toLowerCase((char[]){"HELLO WORLD"});
as changing the strings literal is an UB.
your function should return the string for easy use as parameter.
char *toLowerCase(char* string)
{
int i=0;
while (string[i])
{
if (string[i] >= 'A' && string[i] <= 'Z')
{
string[i] += 'a' - 'A';
}
i++;
}
return string;
}
int main()
{
puts(toLowerCase((char[]){"HELLO WORLD"}));
return 0;
}
I'm trying to write a function for printing text in C for PIC microcontrollers (I think it's based on gcc).
void print(char[] text);
void print(char[] text)
{
for(ch = 0; ch < sizeof(text); ch ++)
{
do_something_with_character(text[ch]);
}
}
and call it like this:
print("some text");
I'm getting compiler complaints about wrong brackets.
What is wrong with this?
How can I use char array pointer in this case?
The correct syntax is
void print(char text[])
or
void print(char *text)
In print(), you cannot use sizeof operator to find out the length of string text, you need to use strlen() (include <string.h> first) or test whether text[ch] is \0.
I would do it like this:
void print(char *text);
void print(char *text)
{
while(*text)
{
do_something_with_character(*text);
++text;
}
}
As mentioned in other answers, your syntax is incorrect. The brackets belong after text.
Also of significant importance, sizeof does not do what you're expecting here:
void print(char[] text)
{
for(ch = 0; ch < sizeof(text); ch ++)
^^^^^^
Remember, sizeof is a compile-time operator - the compiler replaces it with the size while the code is being built. It can't possibly know the size at runtime.
In this case, sizeof(text) is always going to return sizeof(void*), or 4 on most 32-bit systems. Your platform may vary.
You have two options:
Pass the length in another parameter to print.
Treat the char[] as a "C string", where the length is unknown, but the string is terminated by NUL character.
The latter is your best bet, and you should probably replace char[] with char*.
Here we use a NUL-terminated string, and iterate over it with a pointer:
void print(const char* text)
{
const char* p;
// Iterate over each character of `text`,
// until we reach the NUL terminator
for (p = text; *p != '\0'; p++) {
// Pass each character to some function
do_something_with_character(*p);
}
}
You have to place the square brackets in the correct place:
void print(char[] text);
void print(char[] text)
void print(char text[]);
void print(char text[])
or use pointer notation:
void print(char *text);
void print(char *text)
Also, note that even if you use the array notation, the parameter is effectively rewritten to a pointer, and then the code in the body of the function:
for(ch = 0; ch < sizeof(text); ch ++)
is wrong. You almost certainly don't want the 4 or 8 bytes that is the size of the pointer. You probably want:
size_t len = strlen(text);
for (size_t ch = 0; ch < len; ch++)
If you can't declare variables in your loop (C99 or later required), declare it separately. You didn't show the declaration of ch in your code. If it compiled, that means ch is a global variable — which is pretty horrid.
Note that the ++ operator binds tightly and should not be separated from its operand by spaces.
Pass C-style string by pointers, or brackets after variable name:
void print(char *text);
^
or
void print(char text[]);
^^
To calculate the length of a string, use strlen not sizeof.
int len = strlen(text);
for(ch = 0; ch < len; ch ++)
^^^^
Judging on your question and the observation that you are probably a beginner in C, I'll attempt to answer your question without using pointers like the other answers here.
First off, Jonathon Reinhart makes an excellent point, that sizeof is not the proper usage here. Also, as others pointed out, the correct syntax for an array of characters, which is what you are using in your code, is as follows:
// empty character array
// cannot be changed or given a value
char text[];
// character array initialized to the length of its content
char text[] = "This is a string";
// character array with length 1000
// the elements may be individually manipulated using indices
char text[1000];
In your case, I would do something like this:
#include <string.h>
void print(char text[]);
int main()
{
char text[] = "This is a string";
print(text);
return 0
}
void print(char text[])
{
// ALWAYS define a type for your variables
int ch, len = strlen(text);
for(ch = 0; ch < len; ch++) {
do_something_with_character(text[ch]);
}
}
The standard library header string.h provides the strlen function which returns an integer value (actually an unsigned long) of the length of the string excluding the terminating NULL character \0. In C, strings are just arrays of characters and the way you specify the end of a string is by including \0 at the end.
I'm trying to check if a character belongs to a list/array of invalid characters.
Coming from a Python background, I used to be able to just say :
for c in string:
if c in invalid_characters:
#do stuff, etc
How can I do this with regular C char arrays?
The less well-known but extremely useful (and standard since C89 — meaning 'forever') functions in the C library provide the information in a single call. Actually, there are multiple functions — an embarrassment of riches. The relevant ones for this are:
7.21.5.3 The strcspn function
Synopsis
#include <string.h>
size_t strcspn(const char *s1, const char *s2);
Description
The strcspn function computes the length of the maximum initial segment of the string
pointed to by s1 which consists entirely of characters not from the string pointed to by
s2.
Returns
The strcspn function returns the length of the segment.
7.21.5.4 The strpbrk function
Synopsis
#include <string.h>
char *strpbrk(const char *s1, const char *s2);
Description
The strpbrk function locates the first occurrence in the string pointed to by s1 of any
character from the string pointed to by s2.
Returns
The strpbrk function returns a pointer to the character, or a null pointer if no character
from s2 occurs in s1.
The question asks about 'for each char in string ... if it is in list of invalid chars'.
With these functions, you can write:
size_t len = strlen(test);
size_t spn = strcspn(test, "invald");
if (spn != len) { ...there's a problem... }
Or:
if (strpbrk(test, "invald") != 0) { ...there's a problem... }
Which is better depends on what else you want to do. There is also the related strspn() function which is sometimes useful (whitelist instead of blacklist).
The equivalent C code looks like this:
#include <stdio.h>
#include <string.h>
// This code outputs: h is in "This is my test string"
int main(int argc, char* argv[])
{
const char *invalid_characters = "hz";
char *mystring = "This is my test string";
char *c = mystring;
while (*c)
{
if (strchr(invalid_characters, *c))
{
printf("%c is in \"%s\"\n", *c, mystring);
}
c++;
}
return 0;
}
Note that invalid_characters is a C string, ie. a null-terminated char array.
Assuming your input is a standard null-terminated C string, you want to use strchr:
#include <string.h>
char* foo = "abcdefghijkl";
if (strchr(foo, 'a') != NULL)
{
// do stuff
}
If on the other hand your array is not null-terminated (i.e. just raw data), you'll need to use memchr and provide a size:
#include <string.h>
char foo[] = { 'a', 'b', 'c', 'd', 'e' }; // note last element isn't '\0'
if (memchr(foo, 'a', sizeof(foo)))
{
// do stuff
}
use strchr function when dealing with C strings.
const char * strchr ( const char * str, int character );
Here is an example of what you want to do.
/* strchr example */
#include <stdio.h>
#include <string.h>
int main ()
{
char invalids[] = ".#<>#";
char * pch;
pch=strchr(invalids,'s');//is s an invalid character?
if (pch!=NULL)
{
printf ("Invalid character");
}
else
{
printf("Valid character");
}
return 0;
}
Use memchr when dealing with memory blocks (as not null terminated arrays)
const void * memchr ( const void * ptr, int value, size_t num );
/* memchr example */
#include <stdio.h>
#include <string.h>
int main ()
{
char * pch;
char invalids[] = "#<>#";
pch = (char*) memchr (invalids, 'p', strlen(invalids));
if (pch!=NULL)
printf (p is an invalid character);
else
printf ("p valid character.\n");
return 0;
}
http://www.cplusplus.com/reference/clibrary/cstring/memchr/
http://www.cplusplus.com/reference/clibrary/cstring/strchr/
You want
strchr (const char *s, int c)
If the character c is in the string s it returns a pointer to the location in s. Otherwise it returns NULL. So just use your list of invalid characters as the string.
strchr for searching a char from start (strrchr from the end):
char str[] = "This is a sample string";
if (strchr(str, 'h') != NULL) {
/* h is in str */
}
I believe the original question said:
a character belongs to a list/array of
invalid characters
and not:
belongs to a null-terminated string
which, if it did, then strchr would indeed be the most suitable answer. If, however, there is no null termination to an array of chars or if the chars are in a list structure, then you will need to either create a null-terminated string and use strchr or manually iterate over the elements in the collection, checking each in turn. If the collection is small, then a linear search will be fine. A large collection may need a more suitable structure to improve the search times - a sorted array or a balanced binary tree for example.
Pick whatever works best for you situation.