Accessing a string using counter variable in C/C++ [duplicate] - c

This question already has answers here:
Closed 10 years ago.
Possible Duplicate:
In C arrays why is this true? a[5] == 5[a]
In a C++ reference book, I found an example that accessed a string like following:
void main()
{
char *str = "Test";
int len, i;
clrscr();
len = strlen(str);
for(i=0 ; i<len ; i++)
{
printf("%c", i[str]);
}
getch();
}
Why does i[str] work? i is a variable, not an array.
It also works if the string is declared as str[] instead of *str.

Char pointers point to the memory location at the start of a string, and the array indexes (eg, str[i]) are basically adding i iterations to the start of the string.
So, str + i = str[i] = i[str] = i + str
Using this inside printf, like you are doing, all of these will evaluate the same:
printf("%c", str[i]);
printf("%c", i[str]);
printf("%c", *(str+i));
printf("%c", *(i+str));
See also: With arrays, why is it the case that a[5] == 5[a]?

It works because in C i[str] and str[i] are equivalent

i[str] and str[i] evaluate the same way (as *(str+i) )
When you declare str[], str is a pointer to the first element of the array

Related

How to create a function that changes characters of a string?

I'm new to coding and I've been studying C recently. Basically, I wanted to create the following function, which modifies every string element:
char *stralt(char *s, char ch)
{
int i;
for (i=0; i!='\0'; i++)
s[i] = ch;
return s;
}
And when I try to use it on int main(), like this:
int main()
{
printf("%s", stralt("test",'x'));
}
The prompt shows "test" instead of "xxxx". What is wrong with this code and how could it work properly?
Thanks!
You have two problems, one of which isn't apparent because the other doesn't allow it to occur.
You have:
for (i = 0; i != '\0'; i++)
Here, you compare the value of i against '\0', which is 0. Since i is 0 at the beginning of the for loop, the condition i != '\0' will be false, and the loop will exit before entering the body.
It seems that you meant to say:
for (i = 0; s[i] != '\0'; i++)
The other problem is that you're trying to modify a string literal. s[i] = ch; is invalid if s points to a string literal, as it does in your example.
Instead, you have to have a modifiable array of characters. This could be accomplished by modifying your main like:
int main()
{
char test_str[] = "test";
printf("%s", stralt(test_str, 'x'));
}

how to compare strings with for in C [duplicate]

This question already has answers here:
How does c compare character variable against string?
(3 answers)
Closed 1 year ago.
#include <stdio.h>
#include<string.h>
int main(void) {
char* a = "asdf";
for (int i = 0; i < strlen(a); i++) {
if(a[i] == "s"){
printf("%c", a[i]);
}
}
return 0;
}
I think this print "s" but it doesn't print anything what's the problem?
In your example type of "s" is a char *, so your comparison is between a char and a char *. You have to use 's', this type is a char.
To understand the difference try : printf("|%c|\n", "s"); and printf("|%c|\n", 's');

Lowercase to uppercase letters problems in C - segmentation fault [closed]

Closed. This question is not reproducible or was caused by typos. It is not currently accepting answers.
This question was caused by a typo or a problem that can no longer be reproduced. While similar questions may be on-topic here, this one was resolved in a way less likely to help future readers.
Closed 5 years ago.
Improve this question
i have a segmentation fault error when i want to run the executable file
void lowerupper(char *s){
int i ;
int a = strlen (s);
printf("%d\n", a);
//fails here segmentation fault
for (i=0 ; i < a-1 ; i++){
if( (s[i] >= 97) && (s[i] <= 122)){
s[i] = s[i] - 32;
}
}
}
int main(void) {
char* string1 = 'HeLlo wOrlD';
printf("%s\n", string1);
lowerupper(string1);
printf("%s\n", string1);
return 0;
}
You can not modify string1. In fact when you declare a string like this
char* string1 = "HeLlo wOrlD";
The string could be stored into a READ-ONLY memory area, it means that you can read it, but not modify it.
If you do
char array[] = "hello world";
Then it creates a read-only string, and copies the characters into array, you'll be able to modify it (into array).
You are invited to declare read-only strings with the keyword const.
const char *string1 = "HeLlo wOrlD";
You might have been passing address of local variable to the function.
You should allocate memory in heap and then pass that variable to function.
This code works here:
#include <stdio.h>
#include<string.h>
#include<stdlib.h>
void lowerupper(char *s)
{
int i ;
int a = strlen (s);
printf("%d\n", a);
for (i=0 ; i < a-1 ; i++)
{
if( (s[i] >= 97) && (s[i] <= 122))
{
s[i] = s[i] - 32;
}
}
}
int main(void)
{
char *ss=malloc(10);
strcpy(ss,"hello\n");
lowerupper(ss);
printf("%s",ss);
return 0;
}
Sample Output:
6
HELLO

i am trying to do string reverse in a diffrent way

**i am trying to reverse a string so what i am trying is to take the string to its last position and from there i am storing it to a new character array and printing that but not getting desired output **
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
int main()
{
char c[10];
printf("Enter the string:\n");
gets(c);
rev(c);
return 0;
}
void rev(char c[])
{
int i = 0,j = 0;
char s[10];
while(c[j] ! = '\0')//reaching to end of string
{
j++;
}
while(s[i] ! = '\0')
{
s[i] = c[j];//copying string c from end into string s from begining
i++;
j--;
}
s[i+1]='\0';
printf("The string after reverse: %s",s);//printing reversed string
}
while(s[i] ! = '\0')
In above line s[i] is uninitialized and hence you are invoking undefined behaviour by accessing uninitialized value and thus incorrect result.
To fix this, you can rewrite the condition as:
while(j >= 0)
Apart from these, for sane result, you need following two changes:
The final termination should be re-written as:
s[i]='\0';
The initial value of j should be decremented by 1. (As c[j] would point to the null character)
as i is now already pointing past the size of c string.
problem is when you use gets() the buffer is usually dirty. I would suggest you use fflush(stdin) before the gets().
Also the last line where you say s[i+1] = '\0' should be s[i] = '\0' the i already was incremented by one after the last execution of the loop.
And as said above it shouldnt be while (s[i] != '\0')
s is not initialized so God knows whats in there. make it like while ( j >=0) and it should work.

Character Counting in a String - C program

I have written a C program. It's a character counting program. I will give input as below
Input: ABCAPPPRC
And need as output: A2B1C2P3R1.
But it gives output as A2B1C2A1P3P2P1R1C1. It basically doing as per the logic I have written in program. But I don't want to count the characters of string which have already been counted. Can you suggest what logic I should implement for this?
#include <stdio.h>
int main()
{
char str[30]= "ABCAPPPRC";
char strOutPut[60]="";
char *ptr= &str, *ptr2=&str;
char ch='A';
int count=0;
puts(str);
while (*ptr !=NULL)
{
count =0;
ch = *ptr;
while (*ptr2!= NULL)
{
if (*ptr2 == ch) count++;
ptr2++;
}
printf("%c%d",*ptr, count);
ptr++;
ptr2 = ptr;
}
}
You need to separate the counting from the printing.
The first loop goes through the input and counts the number of occurrences of each character, storing the counts in an array indexed by the character code.
The second loop goes through the array of counts and prints the character corresponding to a non-zero count followed by that count.
For example:
#include <stdio.h>
int main(void)
{
char str[] = "ABCAPPPRC";
int counts[256] = { 0 };
puts(str);
for (char *ptr = str; *ptr != '\0'; ptr++)
counts[(unsigned char)*ptr]++;
for (int i = 0; i < 256; i++)
{
if (counts[i] != 0)
printf("%c%d", i, counts[i]);
}
putchar('\n');
return(0);
}
Sample output:
ABCAPPPRC
A2B1C2P3R1
I could not understand the first for loop. Could you please explain it?
The for control line steps through the string str one character at a time. It is the for loop equivalent of the outer while loop in your original code.
char *ptr = str;
...
while (*ptr != '\0')
{
...
ptr++;
}
The body of the loop converts *ptr (a plain char) into an unsigned char (so that it is guaranteed to be positive), and then uses that value as an index into the array counts. Thus, for example, on the first iteration, A is mapped to 65, and counts[65] is incremented. Thus, for each character code, the loop increments the count corresponding to that character code each time the character is encountered in the string.
The second loop then picks out the non-zero counts, printing the character code as a character followed by its count.
(Incidentally, you should have been getting a compilation warning from the original char *ptr = &str about a type mismatch between char * and char (*)[30]. Learn when to put ampersands in front of array names — you seldom do it unless there is also a subscript after the array name. Thus, &array is usually — but not always — wrong; by contrast, &array[0] is very often valid. Also note that on some machines, NULL is defined as ((void *)0) and this elicits a warning when you compare it to a plain char, as you did with while (*ptr != NULL). You should compare characters to '\0' as in my rewrite; you should reserve NULL for use with pointers.)
str is alerady a character pointer, so when you do this: char *ptr= &str you convert a pointer to pointer to character to a char*. Loose the ampersand(&).
Also in the inner cycle you should check if the given value of ch has already been processed. In the case you use when ptr is pointing to the second A you should just continue, because you have already added the number of A-s in the answer.
Your solution is far from optimal. I strongly suggest you lookup counting sort. It will make your solution faster but also will make it simpler.
# Jonathan your solution is correct only when string characters are given in ascending order like ABCDEF, but it gives problem when character order is changed. Input string is "ABAPPPRCC" and required output is A2B1P3R1C2.
Here in this case your solution will change out put to A2B1C2P3R1.
Below program gives character count without changing string formation.
char *str= "ABAPPPRCC";
char strOutPut[30]="";
char *ptr = str, *ptr2 = str;
char ch='A';
int count=0, i = 0 , total_print = 0;
puts(str);
while (*ptr != '\0')
{
count =0;
ch = *ptr;
while (*ptr2!= '\0')
{
if (*ptr2 == ch) count++;
ptr2++;
}
for( i = 0; i < total_print ; i++ )
{
if ( ch == strOutPut[i] )
{
i = total_print + 1;
break;
}
}
if( i <= total_print )
{
printf("%c%d",*ptr, count);
strOutPut[total_print++] = ch;
}
ptr++;
ptr2 = ptr;
}
#include <stdio.h>
int main(void){
const char noncountchar = '\x11';
char str[30]= "ABCAPPPRC";
char strOutPut[60]="";
char *ptr, *ptr2;
char ch;
int count=0, len=0;
puts(str);
for(ptr=str;ch=*ptr;++ptr){
if(ch == noncountchar) continue;
count =1;
for(ptr2=ptr+1;*ptr2;++ptr2){
if (*ptr2 == ch){
*ptr2 = noncountchar;
++count;
}
}
len += sprintf(strOutPut+len, "%c%d", *ptr, count);
}
printf("%s", strOutPut);
return 0;
}

Resources