How do I convert a string to uppercase using the standard library? - c

I am trying to use a for loop with ASCII table to make every character in the string uppercase one by one by subtracting the letter number with 32. but I cant use the int i in the char str and str2. how can I do this?
#include <stdio.h>
#include <ctype.h>
#include <string.h>
#define STRLEN 200
void string_lower() {
}
void string_upper(char str) {
char str2;
int length = strlen(str);
for (int i = 0; i < length; i++) {
str2[i] = str[i - 32];
}
}
int main() {
char word[STRLEN] = { 0 };
char word1 = 97;
printf("Write a word");
fgets(word, STRLEN, stdin);
string_upper(word);
return 0;
}

You can use toupper() to uppercase one character at a time. This will work for single byte character sets such as ASCII, but not for the UTF-8 encoding in general use today for non English scripts.
Here is a modified version:
#include <ctype.h>
#include <stdio.h>
#define STRLEN 200
char *string_upper(char *str) {
for (size_t i = 0; str[i] != '\0'; i++) {
str[i] = toupper((unsigned char)str[i]);
}
return str;
}
int main() {
char word[STRLEN];
printf("Enter a word: ");
if (fgets(word, STRLEN, stdin)) {
printf("%s", string_upper(word);
}
return 0;
}
The argument must be cast as (unsigned char)str[i] because str[i] has type char and tolower() like all functions and macros from <ctype.h> is only defined for values of the type unsigned char and the special negative value EOF. As char may be signed on some platforms, passing it directly to tolower() would have undefined behavior for negative values such as 'é' and 'ÿ'.

If you just want to make a function to convert your String to upper, maybe you can refer to the below example.
#include <stdio.h>
#include <ctype.h>
#define STRLEN 200
void string2upper(char *str){
int cursor=0;
while(*(str+cursor)!='\0'){
*(str+cursor) = toupper(*(str+cursor));
cursor++;
}
}
void main() {
char String1[STRLEN];
printf("Write a word:\n");
fgets(String1, STRLEN, stdin);
printf("Before : %s\n", String1);
string2upper(String1);
printf("After : %s\n", String1);
}
For the toupper() function, I think you can refer to this Link.
That has a detailed explanation and simple example to understand.
I think to know the function detail is better than only using~

Related

assigning a value within a char array pointer

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define MAX40 40
/* run this program using the console pauser or add your own getch, system("pause") or input loop */
Int40 *parseString(char *str)
{
Int40 *p;
char *ptr;
int i, len, value, ptrValue;
printf("%s\n", str);
for(i = 0; i < 40; i++)
{
if(str[i] == 'a')
{
printf("%c\n", str[i]);
str[i] = '0';
printf("%c\n", str[i]);
}
}
}
int main(int argc, char *argv[])
{
// char string[40] = "
// char *str = string;
Int40 *p;
parseString("0123456789abcdef0123456789abcdef01234567");
return 0;
}
In my parseString function, between the two printf statements, I'm trying to assign the value at the specific point of 'a' to 0. I'm not sure how I'm supposed to be attempting this, and I would like to keep the variables the same as well.
Your problem here is that you are passing to parseString a pointer to a
string literal. Modifying the contents of string literals is undefined behaviour
and most of the times string literals reside in read only memory, that's why
your program crashes.
You have to create an array and initialize it with the string you want, then
pass that array to the function:
#include <string.h>
void parseString(char *str, size_t len)
{
printf("%s\n", str);
for(size_t i = 0; i < len; i++)
{
if(str[i] == 'a')
{
printf("%c\n", str[i]);
str[i] = '0';
printf("%c\n", str[i]);
}
}
}
int main(int argc, char *argv[])
{
char text[] = "0123456789abcdef0123456789abcdef01234567";
parseString(text, sizeof text / sizeof *text);
return 0;
}
Bear in mind when you pass an array to a function, the function gets only a
pointer to the first element of the array. For that reason the function being
called cannot determine the length of the array. It's better practice to pass
the length of the array as well. That's why I added size_t len as an argument
in parseString. In main where the array is declared, I calculate the
length of the array with sizeof text / size *text. Note that this only works
with pure array, if you did sizeof str / sizeof *str in parseString, you
will definitively get a wrong result, that's why you should always pass the
length of the array.
Your program is having undefined behavior.
As per the standard attempting to modify a string literal results in undefined behavior because they may be stored in read-only storage or combined with other string literals.
You are passing string literal to parseString() function:
parseString("0123456789abcdef0123456789abcdef01234567");
and in parseString(), trying to modify it:
str[i] = '0';
Instead, in main() function you can do:
char str[] = "0123456789abcdef0123456789abcdef01234567";
which is equivalent to:
char str[] = {'0','1','2','3','4','5','6','7','8','9','a','b','c','d','e','f','0','1','2','3','4','5','6','7','8','9','a','b','c','d','e','f','0','1','2','3','4','5','6','7','\0'};
[Note the terminating null-character at the end.]
So, you can do:
#include <stdio.h>
void parseString(char *pstr)
{
char * str = pstr;
printf("%s\n", str);
for(int i = 0; str[i] != '\0'; i++)
{
if(str[i] == 'a')
{
printf("%c\n", str[i]);
str[i] = '0';
printf("%c\n", str[i]);
}
}
printf("%s\n", pstr);
}
int main(int argc, char *argv[])
{
char str[] = "0123456789abcdef0123456789abcdef01234567";
parseString(str);
printf("%s\n", str);
return 0;
}
Note that in my program, I am only demonstrating the replacement of 'a' with '0' character. Hence, I removed typedef struct Int40... which exists in OP's code.

Attempting to code a c program to return a string length by dividing the code into two separate functions

I've been through several examples and videos and feel like there's a basic misconception on my part somewhere that I'm not seeing.
#include <stdio.h>
#include <stdlib.h>
int main (void)
{
char String;
char *sendString;
char getString[100];
int counter;
*sendString = String;
printf("\nPlease enter string:\n");
fgets(getString, 100, stdin);
int calcLength(counter);
printf("los1111: %d", counter);
return 0;
}
int calcLength()
{
char *sendString[100];
int counter;
for(counter = 0; *sendString[counter] != '\0'; counter++);
printf("los: %d", counter);
return counter;
}
there are a couple of test 'los' printf functions to see where the code is breaking but that unfortunately is bringing me up nothing. Any help is greatly appreciated.
I think your over complicating it slightly.
In this block of code:
char String;
char *sendString;
char getString[100];
int counter;
*sendString = String;
You don't need most of these char declarations, if you only want to calculate the length of the string from fgets.
This can simply be reduced to:
char getstring[100];
int myStrLen;
Where you only need to give a string buffer to fgets, and an integer declaration myStrLen, used to calculate the final string length.
Additionally, there are some problems with your calcLength() function. You need to pass a char [] parameter to this function, so it knows what string it needs to calculate the length of. It really should be as simple as this:
int
calcLength(char sendstring[]) {
int counter, len = 0;
for (counter = 0; sendstring[counter] != '\0'; counter++) {
len++;
}
return len;
}
With all of these recommendations, your code should look like this:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define BUFFSIZE 100
int calcLength(char sendstring[]);
int
main(void) {
char getstring[BUFFSIZE];
int myStrLen;
printf("\nPlease enter string:\n");
if (fgets(getstring, BUFFSIZE, stdin) != NULL) {
getstring[strlen(getstring)-1] = '\0'; // To remove '\n' character from fgets()
}
myStrLen = calcLength(getstring);
printf("String length = %d\n", myStrLen);
return 0;
}
int
calcLength(char sendstring[]) {
int counter, len = 0;
// Every valid character found, increment a counter
for (counter = 0; sendstring[counter] != '\0'; counter++) {
len++;
}
return len;
}
Note: This code can be improved, but it should help point you in the right direction. I've added some comments in the code for clarification.

Separating a string into smaller strings

I have the following string abcd1234 and I want to find a way to break this string into two different strings, abcd and 1234. I have tried the following code:
char buf[100],*str1,*str2;
int x;
fgets(buf,sizeof(buf),stdin);
str1=strtok(buf,"0123456789 \t\n");
str2=strtok(NULL," \n\t\0");
puts(str1);
puts(str2);
x=atoi(str2);
printf("x=%d", x);
but output is abcd 234. And if I try it with one letter and one number, e.g a2 I take only e on output and x is 0.
As per the man page of strtok()
Each call to strtok() returns a pointer to a null-terminated string containing the next token. This string does not include the delimiting byte. [...]
So, while using "0123456789 \t\n" as the delimiter for the first time, 1 will be treated as the actual delimiter and will not be considered in the subsequent parsing.
You may want to use strcspn() and/or strpbrk() to find out the index for the required sub-strings and parse accordingly.
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <ctype.h>
size_t extract(const char **sp, char *out, int (*test)(int ch));
int main(void){
char buf[100], str1[100], str2[100];
int x;
const char *p = buf;
//size_t len;
fgets(buf, sizeof(buf), stdin);
while(*p){
if(isalpha((unsigned char)*p)){
extract(&p, str1, isalpha);
puts(str1);
} else if(isdigit((unsigned char)*p)){
extract(&p, str2, isdigit);
x = atoi(str2);
printf("%s, x=%d\n", str2, x);
} else {
++p;//skip one char
}
}
return 0;
}
size_t extract(const char **sp, char *out, int (*test)(int ch)){
const char *p = *sp;
while(*p && test((unsigned char)*p)){
*out++ = *p++;
}
*out = '\0';
size_t len = p - *sp;
*sp = p;
return len;
}
Try below code.Hope this will help you.
#include <stdio.h>
#include <string.h>
#include <ctype.h>
int main()
{
char string[]="abcd1234";
char digitStr[10];
char charStr[10];
int i,j = 0,k = 0;
for(i=0;string[i];i++)
{
if(isdigit(string[i]))
{
charStr[j++]=string[i];
}
else
{
digitStr[k++]=string[i];
}
}
charStr[j] = '\0';
digitStr[k] = '\0';
printf("%s %s\n",digitStr,charStr);
}
I realize I'm very late on this one, but this is for if anyone has a similar case
Assuming all input strings are like your example, this method will work.
char buf[100];
fgets(buf, sizeof(buf), stdin);
if (buf[strlen(buf) - 1] == '\n')
buf[strlen(buf) - 1] = '\0';
int x = atoi(strpbrk(buf, "0123456789"));
char letters[number - buf + 1];
memcpy(letters, sizeof(letters) - 1, buf);
letters[sizeof(letters) - 1] = '\0';
//letters is the word
//x is the number as an int, not a string
• Note the if statement after the fgets. This checks that the newline character was read by fgets, and turns it into a NUL character. (essentially truncating the string).
• As for strpbrk(), that's just a function that returns a pointer to the first occurence of any character in the second string inside the first string. I use it here to find the start of the digit sequence.
• I would also drop the atoi() for strtol() for safety.
• The letters[] array size is the return of strpbrk() (the address of the first number), minus the start of the array (giving the length of the letter string in bytes), plus one for the NUL character I add later.

Substitution Cipher - issues modifying strings

The following code is broken when trying to run due to an issue replacing the character on line 33. Am I replacing the character in the string incorrectly?
The code is designed to encrypt lowercase characters in the *cat string. Each character in code2 is 'mapped' to a character in the same position in code1. The lowercase chars in *cat are replaced with their substituted char from code2.
//Ben Adamson
//v1.0
#include <stdio.h>
#include <conio.h>
#include <string.h>
#include <ctype.h>
void code(char *s);
int main()
{
char *cat = "The cat sat";
code(cat);
_getch();
return 0;
}
void code(char *s)
{
char code1[] = "abcdefghijklmnopqrstuvwxyz";
char code2[] = "bpduhijkaltxwmrzfoysvngeqc";
char *letter;
unsigned int i, letterpos;
for(i=0; i<strlen(s); i++)
{
if(isalpha(s[i]) && islower(s[i]))
{
letter = strchr(code1, s[i]);
letterpos = (int)(letter - code1);
s[i] = code2[letterpos];
}
}
printf("New string is %s", s);
}
char *cat = "The cat sat";
Her cat is read only.
s[i] = code2[letterpos];
You need to allocate memory if you need to write to it.
char *cat = malloc(100);
Better way to do it is:
char *cat = strdup("The cat sat");

Printing a C string in reverse without using pointers?

Is there a way to print a string of fixed size in reverse without using pointers?
#include<stdio.h>
main()
{
char buffer[10];
scanf("%s", buffer);
// need to print buffer in reverse without using pointers??
}
A lovely K&R function to reverse your string in-place before printing it, perhaps?
#include <stdio.h>
#include <string.h>
void strrev(char *s) {
int tmp, i, j;
for (i = 0, j = strlen(s) - 1; i < j; i++, j--) {
tmp = s[i];
s[i] = s[j];
s[j] = tmp;
}
}
int main(int argc, const char *argv[]) {
char buffer[10];
scanf("%s", buffer);
strrev(buffer);
printf("%s\n", buffer);
return 0;
}
#include<stdio.h>
main()
{
char buffer[10];
int n = scanf("%s", buffer);
// print the number of chars written to buffer
if (n != EOF) {
int len = strlen(buffer);
if (len <= 10) {
int i;
for (i = len - 1; i >= 0; i--)
printf("%c", buffer[i]);
}
}
}
Since [] is just syntactic sugar for pointers, here's a version that works completely without pointers, arrays or anything else, just one single int. You didn't say that the string has to be stored somehow. :) (Note that I use fgetc instead of a buffer and scanf).
[jkramer/sgi5k:.../c]# cat rev.c
#include <stdio.h>
#include <stdlib.h>
void read_print();
int main(void) {
fputs("Enter your string, yo! ", stdout);
read_print();
fputs("\nDone!\n", stdout);
return EXIT_SUCCESS;
}
void read_print() {
int c = fgetc(stdin);
if(c != EOF && c != '\n') {
read_print();
fputc(c, stdout);
}
}
[jkramer/sgi5k:.../c]# gcc -o rev rev.c -Wall -W -Os
[jkramer/sgi5k:.../c]# ./rev
Enter your string, yo! foobar
raboof
Done!
Here's a recursive way of doing it; technically, this is using a pointer, but I wouldn't go into language-lawyer mode with such simple tasks.
#include <stdio.h>
/* If you want it printed forward, or backward, or think of another way.. */
typedef enum {
FRONT = 1,
BACK,
} direction;
/* Technically still using a pointer...don't nitpick. */
void echo_string(char buffer[], size_t buflen, direction from)
{
/* An index into the buffer to echo, which will preserve
* its value across subsequent recursive calls.
*/
static size_t index = 0;
/* According to the specified direction, print from the front
* or the back of the buffer. Advance the index (a misnomer, I guess).
*/
if(from == FRONT) {
printf("%c", buffer[index++]);
}
else {
printf("%c", buffer[buflen - ++index]);
}
/* Are there any more characters to echo? Yes? Awesome! */
if(index != buflen) {
echo_string(buffer, buflen, from);
}
}
int main(int argc, char **argv)
{
char buffer[10];
scanf("%s", buffer);
/* Better strlen() than sizeof() here,
* but BEWARE! scanf() is DANGEROUS!
*/
echo_string(buffer, strlen(buffer), BACK);
return(0);
}
reverse(char c[], int len)
{
if( ! (len / 2))
return;
char t = c[0];
c[0] = c[len--];
c[len] = t;
reverse(c, len-1);
}
The error(s) is left as an exercise to the student.
As caf pointed out, we're still using pointers..!
Here's an other way to solve the problem (of reversing a string).
This code snippet (and probably most others) don't respect stuff like utf8. I think signines post demonstrating the K&R way was quite close to mine (:D) so I adapted mine to fit that example (and corrected some things..)
#include <stdio.h>
#include <string.h>
void strrev(char *s) {
size_t len = strlen(s) + 1;
size_t i, j;
for(i = 0; i < len / 2; i++) {
j = len-1 - i-1;
char tmp = s[j];
s[j] = s[i];
s[i] = tmp;
}
}
int main(int argc, const char *argv[]) {
char buffer[10];
scanf("%s", buffer); // Look out for an overflow ;)
strrev(buffer);
puts(buffer);
return(0);
}
You can use strrev to reverse a string.
#include <stdio.h>
#include <string.h>
main()
{
char buffer[10];
scanf("%s", buffer);
strrev(buffer);
printf("%s", buffer);
}
void outstrreverse(const char s[])
{
size_t l=strlen(s);
while( l && s!=&s[--l] )
putchar(s[l]);
if(s[0])
putchar(s[0]);
}
Because of the relationship between C strings, arrays, and pointers the exercise is rather shotty IMHO - the most idiomatic description of a "String" in C is represented by the char*, which is not an array. Your (the OPs) title and post differ in their definitions between string and char[fixed length].
The OP should read and understand this FAQ entry, and between that and the posts here: easily figure out a solution—as well as defend it to the teacher/judge if need be.
I'll comment on this: never use scanf("%s", buffer) to populate a fixed length string. If you must use scanf() to do it, please use a field width specifier: e.g. scanf("%9s", buffer); if buffer is an [10], you want a specifier of 9 because of how scanf fills the buffer: otherwise you must beware the dragons! You could also scanf by character and evade the issue with a loops bounds, but that would likely be less efficient.
#include <stdio.h>
#include <conio.h>
void reverse(char a[], int s, int sc );
void reverse(char a[], int s, int sc ){
if ((sc-s)<(s-1))
{
a[sc-s]^=a[s-1];
a[s-1]^=a[sc-s];
a[sc-s]^=a[s-1];
reverse (a, s-1, sc) ;
}
}
void main (){
char a[]="ABCDEFG";
reverse(a, 7, 7);
printf("%d",a);
getch(); //i just use it to freeze the screen
}

Resources