tolower() function problems - c

this is my example code:
#include<stdio.h>
#include<string.h>
#include<ctype.h>
void convert(char *a, char *b) {
int i;
for(i=0; i<strlen(a); i++) {
b[i]=tolower(a[i]);
}
}
int main() {
char a[20], b[20];
fgets(a, sizeof(a), stdin);
convert(a, b);
printf("%s\n", b);
return 0;
}
but sometimes the convert() function convert also one more char than strlen(a) (it's a random char), for example this is an output:
ASDSA
asdsa
%
How can i fix it?

You have to add a nul character ('\0') at the end of b.

As others mentioned, you need to null-terminate the target string. Aside from that, note that you are recalculating the length of a at each iteration of the loop. This will not matter for small strings, but with large strings you will notice that the time to convert is proportional to the square of the string length. The standard idiom is to calculate the length once and use it repeatedly. With those two changes, the function would look like this:
void convert(const char *a, char *b) {
size_t i, len = strlen(a);
for(i = 0; i < len; i++) {
b[i] = tolower((unsigned char) a[i]);
}
b[len] = '\0';
}

strlen returns the length of the string, for instance strlen("hello") is 5.
This does not copy the 0 character used to terminate the string (which means the string in the memory is actually 6 characters long: 'h' 'e' 'l' 'l' 'o' '0')

Related

Why is it showing random numbers? C program to read string letters

So I have to create a program that reads the user input and shows how many times each letter appears in that string, and also how many non-letters but my code for alphabets is showing random numbers..
#include <stdio.h>
#include <string.h>
#define SIZE 100
void readInput (char string[]);
void Calc(char string[], int letters[]);
void
readInput (char string[])
{
printf ("Enter a String:\n");
fgets (string, SIZE, stdin);
string[strlen (string) - 1] = '\0';
}
void
Calc(char string[], int letters[])
{
int c = 0, x;
while (string[c] != '\0')
{
if (string[c] >= 'a' && string[c] <= 'z')
{
x = string[c] - 'a';
letters[x]++;
}
c++;
}
for (c = 0; c < 26; c++)
printf ("%c occurs %d times in the entered string.\n", c + 'a', letters[c]);
}
int
main ()
{
char string[SIZE];
int letters[26];
readInput (string);
Calc(string, letters);
return 0;
}
This is the output
I'm new to strings I've googled examples but can't seem to find whats wrong with my code and no idea how I will include the non-letters part.
The contents of letters are not initialised. Formally the behaviour of your program is indeterminate.
Sort that by writing int letters[26] = {0}; Doing that sets all elements to zero, which is what you want in this case.
letters[] is uniinitialized.
Solution int letters[26]={0}.
You are reading an uninitialized value which is indeterminate. And the results doesn't conform to as you expect it to be.
Here you want to initialize the elements with 0 denoting that you haven't seen any charcaters yet. (automatic storage duration).
A better way to overwrite the '\n' would be
string[strcspn(string, "\n")] = 0;
you should initialize letters with all 0 values

How to insert an extra character in a string in C

#include <stdio.h>
#include <string.h>
void replace(char a[],char b[]);
int main(void)
{
char string1[100]; char string2[100];
printf("Please enter a string:");
fgets(string1, sizeof(string1), stdin);
replace(string1, string2);
}
void replace(char a[],char b[])
{
int i;
strcpy(b,a);
for(i=0;i<strlen(a);i++)
{
if(a[i]=='a')
{
b[i+1]=a[i];
}
}
printf("%s\n",b);
}
The function of this program is to copy string1 into string2 but if there's any 'a' character in string1, it needed to be double in string2.
For example, if string1 is "aeroplane", the string2 needs to be "aaeroplaane".
However, the code above seem to change the next character after 'a' in string1 instead of simply adding it. For example, if I type "aloha", it will simply give me "aaoha" instead of "aalohaa". I've tried searching online but to no avail. I've been sticking on this problem for hours.
In order to work you must implement your replace function correctly
It should be like:
void replace(char a[],char b[])
{
int idxA = 0, idxB = 0;
for(idxA;idxA<strlen(a);idxA++, idxB++)
{
b[idxB] = a[idxA];
if(a[idxA]=='a')
{
idxB++;
b[idxB]=a[idxA];
}
}
b[idxB] = '\0';
printf("%s\n",b);
}
But you must ensure b has enough space to hold the complete string. For example, you can reserve twice the size of a, the worst case when array a has all a characters
Ok, if we are playing code golf, I would suggest:
void replace (char *a, char *b) {
while ((*b++ = *a))
if (*a++ == 'a')
*b++ = 'a';
}
;)
Mind to provide enough memory in b; if you want to play it safe, it has to be at least strlen(a)*2+1 (the case a consists only of character "a").
For the sake of brevity and elegance, here's a one liner:
void replace (char *a, char *b) { while((*b++=*a)&&(*a++!='a'||(*b++='a'))); }
;)
with
b[i+1]=a[i]
you're changing the next character to be 'a' and overwriting the next character.
What should be done is moving all the characters after b[i+1] one step forward and then changing 'a' in b[i+a]
void replace(char a[],char b[])
{
int i = 0, j = 0;
for(i=0; i<strlen(a); i++, j++)
{
b[j] = a[i];
if(a[i] == 'a')
b[++j] = a[i];
}
}
see if this works.
I wont solve it for you.
But here is what you need to look into.
if(a[i]=='a')
{
b[i+1]=a[i];
}
What it is doing is, if ith index of a array is 'a' then write ith index of a array in i+1th location of array b.
This way you are over-writing the contents of b.
You need to make a place for an additional character there only after shifting the string from that index to right.
It can be done in multiple ways.
Additionally, you might want to allocate more size (ideally twice: To cover the case when you pass a string1 with 100 'a's, the resulting string2 should hold 200 'a's) to your second array than the first one, because of obvious reasons.
You want this:
#include <stdio.h>
#include <string.h>
void replace(char a[], char b[]);
int main(void)
{
char string1[100]; char string2[100];
printf("Please enter a string:");
fgets(string1, sizeof(string1), stdin);
replace(string1, string2);
printf("%s\n", string2); // printf result from replace here
}
void replace(char a[], char b[])
{
int i, j; // using two indexes, one for a and one for b
// no strcpy needed here, copying is done in the for loop below
for (i = 0, j = 0; i < strlen(a); i++, j++)
{
b[j] = a[i]; // copy one char
if (a[i] == 'a') // if it's 'a'
{
b[++j] = a[i]; // copy it again
}
}
b[j] = 0; // terminate the destination string
// we don't printf b here but in main
}
For brevity no buffer overflow checking is done here.
There is still room for improvement though.

Would does this function which converts a char array to an int array not work?

This program is supposed to convert the array of chars (string) into an array of ints by subtracting 97 from their ascii value (the input should be lower case cause a has an ascii value of 97). So if i enter the string abcd i should get 0123 but instead I somehow get this: 012134513789. I can't figure out where the problem is.
#include <stdio.h>
#include <stdlib.h>
#include <stdbool.h>
void userEnter(int*pattern, int n);
int main(void)
{
int n, i;
printf("What is the length of the array: ");
scanf("%d",&n);
int pattern[n];
printf("Enter the char array: ");
userEnter(pattern, n);
printf("The int array is: ");
for(i=0;i<n;i++)
{
printf("%d",pattern[i]);
}
printf("\n");
}
void userEnter(int*pattern, int n)
{
char input[n];
scanf("%s", input);
int i;
for(i = 0; i < n-1; i++)
{
pattern[i] = input[i]-97;
}
}
char input[n];
scanf("%s", &input);
should be
char input[n+1];
scanf("%s", input);
input is equivalent to &input[0]
You should also exit the for loop in userEnter when you encounter the nul character that ends the user-entered string. e.g. with something like
char* p = input;
while (*p != '\0') {
*pattern = (*p) - 'a';
p++;
pattern++;
}
As KingsIndian points out, you also need to increase the size of your input buffer. At present, you overflow that buffer and overwrite the loop counter i;
The length parameter n includes one character for null as well. So, if you input length for n 4 then you can only input 3 characters, for example abc because the 4th is for the null.
So you should change the declaration accordingly:
Change:
char input[n];
to:
char input[n+1];
Note that variable length arrays are allowed only since C99.

How get ASCII of a string

i need to get the ascii (int and hex format) representation of a string char by char. For example if i have the string "hello", i would get for int ascii 104 101 108 108 111
and for hex 68 65 6C 6C 6F
How about:
char *str = "hello";
while (*str) {
printf("%c %u %x\n", *str, *str, *str);
str++;
}
In C, A string is just a number of chars in neighbouring memory locations. Two things to do: (1) loop over the string, character by character. (2) Output each char.
The solution for (1) depends on the string's representation (0-terminated or with explicit length?). For 0-terminated strings, use
char *c = "a string";
for (char *i = c; *i; ++i) {
// do something with *i
}
Given an explicit length, use
for (int i = 0; i < length; ++i) {
// do something with c[i]
}
The solution for (2) obviously depends on what you are trying to achieve. To simply output the values, follow cnicutar's answer and use printf. To get a (0-terminated) string containing the representation,
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
/* convert a 0-terminated string to a 0-terminated string of its ascii values,
* seperated by spaces. The user is responsible to free() the result.
*/
char *to_ascii(const char *inputstring) {
// allocate the maximum needed to store the ascii represention:
char *output = malloc(sizeof(char) * (strlen(inputstring) * 4 + 1));
char *output_end = output;
if (!output) // allocation failed! omg!
exit(EXIT_FAILURE);
*output_end = '\0';
for (; *inputstring; ++inputstring) {
output_end += sprintf(output_end, "%u ", *inputstring);
//assert(output_end == '\0');
}
return output;
}
If you need to output an explicit-length string, use strlen() or the difference (size_t)(output_end-output).
int main()
{
enum type {decimal, hexa};
char *str = "hello";
char *temp_str = NULL;
temp_str = str;
static enum type index = decimal;
while (*str) {
if(index == decimal)
printf("%u\t", *str);
else
printf("%x\t",*str);
str++;
}
printf("\n");
if(index != hexa)
{
index = hexa;
str = temp_str;
main();
}
}
hope this will work fine as what u want, and if u want to store it in a uint8_t array, have to just declare an variable for it.
I know this is 5 years old but my first real program converted strings to ASCII and it was done in a clean and simple way by assigning a variable to getchar() and then calling it in printf() as an integer, all while it's in a loop of course, otherwise getchar() only accepts single characters.
#include <stdio.h>
int main()
{
int i = 0;
while((i = getchar()) != EOF)
printf("%d ", i);
return 0;
}
and here's the original version using the for() loop instead because I wanted to see just how small I could make the program.
#include <stdio.h>
int main()
{
for(int i = 0; (i = getchar()) != EOF; printf("%d ", i);
}
/* Receives a string and returns an unsigned integer
equivalent to its ASCII values summed up */
unsigned int str2int(unsigned char *str){
int str_len = strlen(str);
unsigned int str_int = 0;
int counter = 0;
while(counter <= str_len){
str_int+= str[counter];
printf("Acumulator:%d\n", str_int);
counter++;
}
return str_int;
}

Problems with simple c task

So after a few years of inactivity after studying at uni, I'm trying to build up my c experience with a simple string reverser.
here is my code:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
/*
*
*/
int main(int argc, char** argv) {
reverser();
return(0);
}
int reverser(){
printf("Please enter a String: ");
//return (0);
int len;
char input[10];
scanf("%s",&input);
int quit = strcmp(input,"quit");
if(quit == 0){
printf("%s\n","Program quitting");
return(0);
}
len = strlen(input);
printf("%i\n",len);
char reversed[len];
int count = 0;
while (count <= (len-1)){
//printf("%i\n",(len-count));
reversed[count] = input[(len-1)-count];
count++;
}
//printf("%s\n",input);
printf(reversed);
printf("\n");
reverser();
}
When I input "hello", you would expect "olleh" as the response, but I get "olleh:$a ca&#",
How do I just get the string input reversed and returned?
Bombalur
Add a '\0' at the end of the array. (as in, copy only chars until you reach '\0' - which is the point at array[strlen(array)], then when you're done, add a '\0' at the next character)
Strings are conventionally terminated by a zero byte. So it should be
char reversed[len+1];
And you should clear the last byte
reversed[len] = (char)0;
you forgot the \0 at the end of the string
This is because you are creating an array with size 10. When you take in some data into it (using scanf) and the array is not filled up completely, the printf from this array will give junk values in the memory. You should iterate for the length of the input by checking \n.
must have a size + 1 to string length so that you can have a \0 at the end of string that will solve your problem
The following is a (simple and minimal implementation of) string reverse program (obviously, error conditions, corner cases, blank spaces, wider character sets, etc has not been considered).
#include <stdio.h>
int strlen(char *s)
{
char *p = s;
while (*p)
p++;
return p - s;
}
char * strrev(char a[])
{
int i, j;
char temp;
for (i=0, j=strlen(a)-1 ; i<j ; i++, j--) {
temp = a[i];
a[i] = a[j];
a[j] = temp;
}
return a;
}
int main()
{
char str[100];
printf("Enter string: ");
scanf("%s", str);
printf("The reverse is %s \n", strrev(str));
return 0;
}
Hope this helps!

Resources