In this program i'm trying to invert a string using 2 arrays:
The problem here is the program keeps writing the character "P" as the only output and i can't seem to figure out how to solve this.
#include<stdio.h>
#include<string.h>
#define TAM 256
int get_string(char string[TAM]);
int invert_string(char string[TAM]);
int string_out(char string[TAM]);
int main(){
char string[TAM]={0}; // always initialize a string to be completely zero, or unexpected behaviour may occur
get_string(string);
invert_string(string);
return 0;
}
int get_string(char string[TAM]){
printf("Enter a string: ");
scanf("%s",string);
return 0;
}
int invert_string(char string[TAM]){
char temporary_string[TAM]={0};
int i,j;
for(i=TAM,j=0;i>=0;i--){
if(string[i]== ' '){
continue;
}else{
temporary_string[j] = string[i];
j++;
}
}
printf("debug : temp string is : %s",temporary_string);
return 0;
}
int string_out(char string[TAM]){
printf("%s",string);
return 0;
}
Try this code in invert_string function:
int i,j;
for(i=strlen(string)-1,j=0;i>=0;i--){ // u can take variable and save length or directly pass length
if(string[i]== ' '){
continue;
}else{
temporary_string[j++] = string[i];
}
}
temporary_string[j] = '\0'; //Make last index NULL
printf("%s",temporary_string);
For an array declaration / definition of arr[256], the last element is arr[255].
In your for() loop,
for(i=TAM,j=0;i>=0;i--)
you're accessing arr[256] [267th element, considering index starts from 0] which is out-of-bound access and hence produces undefined behavior.
Then, the terminating NULL in the source array should be taken care of separately.
You need to have something like
if((string[i]== ' ') || (string[i]== '\0')){//....
Otherwise, the terminating NULL will become the first vaild element in the destination array, thus will end up printing nothing.
Lastly, don't forget to NULL terminate the new array.
temporary_string[j] = '\0';
Note: Once you'vre fixed this version of code, think of some optimization.
Check the below code.
#include<stdio.h>
#include<string.h>
#define TAM 256
int get_string(char string[TAM]);
int invert_string(char string[TAM]);
int string_out(char string[TAM]);
int main(){
char string[TAM]={0}; // always initialize a string to be completely zero, or unexpected behaviour may occur
get_string(string);
invert_string(string);
return 0;
}
int get_string(char string[TAM]){
printf("Enter a string: ");
scanf("%s",string);
return 0;
}
int invert_string(char string[TAM]){
char temporary_string[TAM]={0};
int i,j;
for(i=TAM-1,j=0;i>=0;i--){
if((string[i]== ' ') || (string[i]== '\0')){
continue;
}else{
temporary_string[j] = string[i];
j++;
}
}
temporary_string[j] = '\0';
printf("debug : temp string is : %s\n",temporary_string);
return 0;
}
Make you loop condition starting with 255.
for ( i=TAM-1 ; j=0; i>=0 ; i--)
...
256 is array out of bounds.
There are lot of issues with your code. At first you cannot start with 256 as i mentioned in the comment. Again you don't know how much is the length of the source string. Even if u have taken the size to be 256 the string inputted from the terminal can be of length smaller than 256. So first you must know what is the size of the string inputted from the terminal. After that start with strlen(string) - 1 and copy until i becomes 0. Then do temporary_string[strlen(string)-1]='\0'
Related
#include <Stdio.h>
#include <string.h>
int main(){
char str[51];
int k = 1;
printf("Enter string\n");
scanf("%s", &str);
for(int i = 0; i < strlen(str); i++){
while(str[k] != '\0')){
if(str[i] == str[k]){
printf("%c", str[i]);
k++;
}
}
}
return 0;
}
It is simple C code that checks for duplicate characters in string and prints the characters. I am not understanding why it is producing an infinite loop. The inner while loop should stop when str[k] reaches the null terminator but the program continues infinitely.
Points to know
You don't need to pass the address of the variable str to scanf()
Don't use "%s", use "%<WIDTH>s", to avoid buffer-overflow
Always check whether scanf() conversion was successful or not, by checking its return value
Always use size_t to iterator over any array
i < strlen(str), makes the loop's time complexity O(n3), instead of O(n2), which also isn't very good you should check whether str[i] != 0. But, many modern compilers of C will optimize it by the way.
#include <Stdio.h> it is very wrong, stdio.h != Stdio.h
Call to printf() can be optimized using puts() and putc() without any special formatting, here also modern compiler can optimize it
while(str[k] != '\0')){ has a bracket (')')
Initialize your variable str using {}, this will assign 0 to all the elements of str
Better Implementation
My implementation for this problem is that create a list of character (256 max) with 0 initialized, and then add 1 to ASCII value of the character (from str) in that list. After that print those character whose value was greater than 1.
Time Complexity = O(n), where n is the length of the string
Space Complexity = O(NO_OF_CHARACTERS), where NO_OF_CHARACTERS is 256
Final Code
#include <stdio.h>
#include <stdlib.h>
#include <limits.h>
static void print_dup(const char *str)
{
size_t *count = calloc(1 << CHAR_BIT, sizeof(size_t));
for(size_t i = 0; str[i]; i++)
{
count[(unsigned char)str[i]]++;
}
for (size_t i = 0; i < (1 << CHAR_BIT); i++)
{
if(count[i] > 1)
{
printf("`%c`, count = %zu\n", i, count[i]);
}
}
free(count);
}
int main(void) {
char str[51] = {};
puts("Enter string:");
if (scanf("%50s", str) != 1)
{
perror("bad input");
return EXIT_FAILURE;
}
print_dup(str);
return EXIT_SUCCESS;
}
Read your code in English: You only increment variable k if character at index k is equal to character at index i. For any string that has different first two characters you will encounter infinite loop: char at index i==0 is not equal to char at index k==1, so k is not incremented and while(str[k]!=0) loops forever.
#include <stdio.h>
int main()
{
int i, j;
char or[20];
printf("enter your input string\n");
scanf("%[^\n]%*c", &or);
for(i=0;i<20;i++)//to get length of string
{
if(or[i]=='\0')
j=i;
}
char rev[j];//reverse string
for(i=0;i<j ;i++){//inserting spaces into reverse string
if(or[i]==' ')
{
rev[i]=or[i];
}
}
for(i=0;i<j; i++)//inserting characters of original string into reverse string
{
if(or[i]!=' '){
if(rev[j-i]!=' '){
rev[j-i]=or[i];
}
}
}
printf ("%s", rev);//printing reverse string
return 0;
}
enter link description here
in codeblocks it takes input but before showing output
process returned 3.
are any changes needed in code or in IDE?
my input is: hi dude
my expected output is : ed udih
but i get output like this : enter your input string
hi dude
Your algorithm is wrong from inception.
The content of the variable-length array is only set on encounter of a space; the remaining content is indeterminate, and therefore any evaluation tests against invoke undefined behaviour.
The actual reversal storage is wrong. You're advancing the "write" position on each iteration even when you skip an actual write. You need different indexing here.
One plausible solution is this:
#include <stdio.h>
#include <string.h>
int main()
{
char or [20];
printf("enter your input string\n");
if (scanf("%19[^\n]%*c", or ) == 1)
{
size_t len = strlen(or);
char rev[len+1];//reverse string
for (size_t i = 0; i < len; i++)
rev[i] = (or[i] == ' ') ? ' ' : 0;
rev[len] = 0;
for (size_t i = len, k=0; i-- > 0;)
{
// find next 'write' positon. note this will
// do nothing if we're already on top of a
// position ready for storing.
while (rev[k] == ' ')
++k;
// write next char and advance writer index (k)
if (or [i] != ' ') {
rev[k++] = or[i];
}
}
printf("%s", rev);//printing reverse string
}
return 0;
}
Input
one two three four
Output
ruo fee rhtow teno
See it live here
#include<stdio.h>
char bin(int);
int main()
{
setbuf(stdout,NULL);
int num;
char res[50];
printf("Enter the number: ");
scanf ("%d",&num);
res=bin(num);
printf("%s",res);
return 0;
}
char bin(int num)
{
char str[50];
int i,val;
for(i=0;num>=0;i++)
{
val=num%2;
str[i]=val;
num=num/2;
}
return str;
}
I really cant understand the error in the usage of strings... to convert the decimal to binary. Whats the conceptual error Im not following?
char is a single character, so char bin(int) will not be able to return a string (i.e. a null-terminated array of characters). And you cannot "return" an an array of characters, because C does not allow to return any array as function result. You can just pass/return pointers to the begin of such arrays.
So I'd suggest to change the interface of bin to reicieve the result buffer as parameter. Don't forget to "close" the string, i.e. to write the string termination character after the last "actual" character:
void bin(int num, char* resultBuffer) {
...
resultBuffer[i] = '\0';
}
In main, you call it then like
bin(num, res);
Returning str amounts to returning a local variable, you can't do it, what you can do is to return a pointer to a previously allocated memory block that works as an array (as an alternative to the oher answer, which is a good solution).
To do this you can declare str as a pointer, allocate memory for it and return it, making sure the variable to which the value is assigned is also a pointer, all the rest can remain the same.
There are, however, problems with the bin function.
Consider the statement:
str[i] = val;
This will not work as expected you are assigning the int result of the operation, which will be 1 or 0, you need to convert this value to the respective character.
The loop for (i = 0; num >= 0; i++) is an infinite loop because num will never be negative, unless you provide it a negative number in which case it will break in the first iteration, that is to say this code only works with positive integers. You need > instead of >=.
Finally you need to null terminate the string when the conversion is complete.
Corrected code (Online):
#include <stdio.h>
#include <stdlib.h>
char *bin(int); //return pointer
int main() {
setbuf(stdout, NULL);
int num;
char *res; //use pointer to receive string assignment
printf("Enter the number: ");
scanf("%d", &num);
res = bin(num);
printf("%s", res);
return 0;
}
char *bin(int num) {
char *str = malloc(50); // allocate memory
int i, val;
for (i = 0; num > 0; i++) { // replacing >= with >
val = num % 2;
str[i] = val + '0'; // convert to character
num = num / 2;
}
str[i] = '\0'; //null terminate the string
return str;
}
Note that you should also check for the inputed value, if it is larger than what an int variable can hold it will result in undefined behavior.
I have been trying to reverse(and print it that way) a given string only using for loops and nothing more. I think I have built up the basic logic, but it has some defects. When run, it only reverses the first two characters and then stops. Please help me find the defect in my logic.
#include<stdio.h>
#include<stdlib.h>
int main()
{
char a[20];
int i;
printf("Enter any String\n");
gets(a);
for(i=0;a[i]!=NULL;i++)
{}
for(i=1;i>=0;i--)
{
printf("%c",a[i]);
}
}
For starters the function gets is not a standard C function any more. it is unsafe. Instead use the standard C function fgets. The function can append the new line character '\n' to the entered string that should be excluded from the string.
It is unclear from your question whether you are allowed to use standard string functions.
Nevertheless here is a demonstrative program that does the task without using standard C string functions and that uses only for loops (neither while loop nor do-while loop).
#include <stdio.h>
int main(void)
{
enum { N = 20 };
char s[N];
printf( "Enter any String less than %d symbols: ", N );
fgets( s, N, stdin );
// remove the new line character and calculate the length of the string
size_t n = 0;
for ( ; s[n] != '\0' && s[n] != '\n'; ) ++n;
s[n] = '\0';
// reverse the string
for ( size_t i = 0; i < n / 2; i++ )
{
char c = s[i];
s[i] = s[n-i-1];
s[n-i-1] = c;
}
puts( s );
return 0;
}
Its output might look the following way
Enter any String less than 20 symbols: Hello dev.aniruddha
ahddurina.ved olleH
If you want just to output the original string in the reverse order then the program can look like
#include <stdio.h>
int main(void)
{
enum { N = 20 };
char s[N];
printf( "Enter any String less than %d symbols: ", N );
fgets( s, N, stdin );
// remove the new line character and calculate the length of the string
size_t n = 0;
for ( ; s[n] != '\0' && s[n] != '\n'; ) ++n;
s[n] = '\0';
// reverse the string
for ( ; n-- != 0; )
{
putchar( s[n] );
}
putchar( '\n' );
return 0;
}
Its output is the same as shown above
Enter any String less than 20 symbols: Hello dev.aniruddha
ahddurina.ved olleH
gets() is a bad idea as you can easily get overflows and it is no longer part of the c standard.
So let's assume that the string entered fits the array and this is just for an excercise with no reallife usage.
Your first loop finds the terminator. That's good.
Your second loop sets the variable that indicates the terminator to 1, destroying the result.
If you remove the assignment i=1, your program compiles with gcc and does what you want.
#include<stdio.h>
#include<stdlib.h>
int main()
{
char a[20];
int i;
printf("Enter any String\n");
gets(a);
for(i=0;a[i]!=NULL;i++)
{}
for(;i>=0;i--) //removed i=1 here
{
printf("%c",a[i]);
}
}
But there are still some issues to be addressed.
You will also reverse the terminator, instead you should start from i-1
I would advise to not use a for loop if you do not have a counter criterion The first loop should rather be a while loop, but as it was part of the assignment you had no choice still I will replace it in my recommendation. As they can easily be swapped.
Then you could use another variable for the second loop for clarity.
Also NULL is the NULL-pointer not the value 0 (also namend NUL apperantly) . So you should replace this either with 0 or with '\0'
Also stdlib.h is not required here
#include<stdio.h>
int main()
{
char a[20];
int i = 0;
printf("Enter any String\n");
gets(a);
while (a[i] != 0)
{
i++;
}
for(int j = i-1; j>=0; j--) // -1 to get the value in front of the terminator
{
printf("%c",a[j]);
}
printf("\n"); //to flush the output.
}
Here is the solution code.
The first for loop is to be used for determining the length of the string and the second for loop is for traversing the string from the last position to the first.
#include<stdio.h>
int main()
{
char a[20];
int i,j,len;
printf("Enter a String\n");
gets(a);
for(i=0;a[i]!=NULL;i++)
{}
len=i;
for(j=len-1;j>=0;j--)
{
printf("%c",a[j]);
}
}
I think why only two chars are been return is because of the condition statement in your second "for loop".
for(i=1;i>=0;i--)
Note:
it repeats from 1~0 (1,0): meaning it will repeat only twice
first iteration: when i == 1
second iteration: when i == 0 ; then it ends .
Please note that you created two "for loops" with the first one having no content.
Bonus:
I tried to fixed your code but realized that my C language skills isnt the best lol . Anyways, i came up with something that you could reference but it only reverse strings of less than 8 elements.
#include<stdio.h>
#include<stdlib.h>
int findlength(char a[]);
int main()
{
char a[20];
int i;
printf("Enter any String\n");
gets(a);
int len = findlength(a);
printf("Lenght of the String is: %d \n",len);
printf("Reversed String is: ");
for(i=len;i>-1;i--){
printf("%c",a[i]);
}
}
int findlength(char a[]){
int result = 0;
int i;
for(i=0;i<sizeof(a) / sizeof(char);i++){ // sizeof(char) is 1
if(a[i] == '\0') //end of string
return result;
result += 1;
}
return result;
}
I created a program for bubble sort. It ends up in an infinite loop.
I have included comments at places so that the code is easily understandable.
Any suggestions on how to make the code smaller are welcome.
I was debugging the program and found this -
When stdin was "ccbbaa" and after some recursions when finally input(aabbcc) and temp(aabbcc) were same, then after the condition of strcmp() was executed, the value of 'temp' was changed to "baabcc".
Any reasons as to why this happened? — This is the reason for the infinite loop.
Does a character array have a '\0' at the end (while copying input to temp)?
I solved the problem by using a for loop instead of strcmp(). Investigating why strcmp() doesn't work currently.
Updated code is available - http://ideone.com/4Bdblh ( solved )
Buggy code
#include<stdio.h>
#include<string.h>
#include<math.h>
#include<stdlib.h>
#include<ctype.h>
void sort(char* input)
{
const int length = strlen(input);
int j = length -1;
char temp[length];
for(int i=0; i<length; i++)
{
temp[i]= *(input+i);
}
while(j)
{
if((int)*(input+1) < (int)*(input))
{
char temp1;
temp1 = *(input);
*input = *(input + 1);
*(input + 1) = temp1;
}
input++;
j--;
}
input = input - length +1;
while(strcmp(temp,input))
{
sort(input);
}
}
int main()
{
char* input = malloc(sizeof(char)*1000);
scanf("%[^\n]%*c",input);
sort(input);
printf("%s",input);
return 0;
}
Answer using arrays and for loops-
#include<stdio.h>
#include<string.h>
#include<math.h>
#include<stdlib.h>
#include<ctype.h>
#define MAX 1000
void sort(char input[])
{
const int length = strlen(input);
int j = length -1;
char temp[length];
for(int i=0; i<length; i++)
{
temp[i]= input[i];
}
int l=0;
while(j)
{
if(input[l+1] < input[l])
{
char temp1;
temp1 = input[l];
input[l] = input[l+1];
input[l+1] = temp1;
}
l++;
j--;
}
for(int k=0; k<length; k++)
{
if(temp[k]!=input[k])
{
sort(input);
}
}
}
int main()
{
char input[MAX];
scanf("%[^\n]%*c",input);
sort(input);
printf("%s",input);
return 0;
}
In C a string is just a char array ending in 0.
All string functions assume char arrays end with zero.
strcpy copies the string including the 0 delimiter at the end. Therefore, destination must have enough space for the string plus the zero.
strlen returns the length of the string, so the destination must be at least strlen (input)+1 long.
If you copy the string in a loop, then you mustn't forget to add the ending zero.
What I don't really get is why to make it recursive and doing a string comparison to detect completion. You can just implement two nested loops from 0 to length - 2. It's warranted it'll be sorted in the end.
If you want to make it adaptive, just store the last position you swapped. You needn't go further the next loop.
When stdin was "ccbbaa" and after some recursions when finally input(aabbcc) and temp(aabbcc) were same, then after the condition of strcmp() was executed, the value of 'temp' was changed to "baabcc".
Any reasons as to why this happened? — This is the reason for the infinite loop.
It just looked like the value of 'temp' was changed to "baabcc" because the function returned to the previous recursion level where the local temp had the same value as before. The main reason for the infinite loop is that due to the while(strcmp(temp,input)) the old, unsorted temp is compared again and again.
Does a character array have a '\0' at the end (while copying input to temp)?
The temp array in the buggy code hasn't; you could have written
char temp[length+1];
strcpy(temp, input);
or just used strncmp() rather than strcmp().
So, for the program to work it is sufficient to change
while(strcmp(temp,input))
to
if (strncmp(temp, input, length))