The first character in both string won't swap in C [closed] - c

Closed. This question needs debugging details. It is not currently accepting answers.
Edit the question to include desired behavior, a specific problem or error, and the shortest code necessary to reproduce the problem. This will help others answer the question.
Closed 5 years ago.
Improve this question
#include <stdio.h>
#define SIZE 101
void swap(char *a, char *b);
int main(void) {
char string1[SIZE];
char string2[SIZE];
printf("please enter string 1 :");
scanf("%s", string1);
printf("please enter string 2 :");
scanf("%s", string2);
swap(string1, string2);
printf("string 1 is %s, string 2 is %s\n", string2, string1);
}
void swap(char *a, char *b) {
int i;
char temp[101];
for (i = 0; i < SIZE; i++) {
temp[i] = *a;
*a = *b;
*b = temp[i];
}
}
When I give inputs to both string1 and string2 lets say "yes" and "hello", it will print string1 is yello and string2 is hes. I've tried to modify by changing *b to *[b+1] and *a to *[a+1] and it gets the first character to work but now the second character won't swap.
EDIT
Also I've tried another function but the problem is still there.
void swap(char* a, char* b)
{
char temp;
temp=*a;
*a=*b;
*b=temp;
a++;
b++;
}

Your swap function is wrong:
Here is the corrected version:
void swap(char* a, char* b)
{
int i; char temp;
for (i = 0; i<SIZE; i++)
{
temp = a[i];
a[i] = b[i];
b[i] = temp;
}
}
you don't need a temp array, just one char is enough for the temporary.
you need to access the different chars of the input a and b, and not only the first one.
BTW: here is a better version of swap where you pass the size as parameter:
void swap(char* a, char* b, int size)
{
int i; char temp;
for (i = 0; i < size; i++)
{
temp = a[i];
a[i] = b[i];
b[i] = temp;
}
}

Actually only the first characters of your strings is swapped(which makes sense as mentioned in other answers), you don't see this because you change the order of printing with
printf("string 1 is %s, string 2 is %s\n", string2, string1);
^^^^^^^^^^^^^^^
Here you are always just swapping the first character since you a and b always point to first element.
for(i=0; i<SIZE; i++)
{
temp[i]= *a;
*a=*b;
*b=temp[i];
}
you can use array subscript
int i; char temp;
for (i = 0; i < SIZE; i++)
{
temp = a[i];
a[i] = b[i];
b[i] = temp;
}

There are multiple problems in your code:
you print the strings in the wrong order
you only swap the first character, and you do this SIZE times. SIZE is odd so you see it swapped, the previous bug makes it look like the other characters were swapped. If SIZE were even, you would not swap anything and the previous bug would let you erroneously believe everything is fine...
Less important, but worth mentioning:
you do not check the return values of scanf()
you do not return 0 at the end of main().
Here is a corrected and improved version:
#include <stdio.h>
#define SIZE 101
void swap(char *a, char *b, int size) {
for (int i = 0; i < size; i++) {
char temp = a[i];
a[i] = b[i];
b[i] = temp;
}
}
int main(void) {
char string1[SIZE];
char string2[SIZE];
printf("please enter string 1 :");
if (scanf("%s", string1) != 1)
return 1;
printf("please enter string 2 :");
if (scanf("%s", string2) != 1)
return 1;
swap(string1, string2, SIZE);
printf("string 1 is %s, string 2 is %s\n", string1, string2);
return 0;
}

Try to use parentheses like *(a+1) instead of bracket *[b+1]. In your code
change the following
for(i=0; i<SIZE; i++)
{
temp[i]= *a;
*a=*b;
*b=temp[i];
}
with
for(i=0; i<SIZE; i++)
{
temp[i] = *(a+i);
*(a+i) = *(b+i);
*(b+i) = temp[i];
}
Final code is here:
#include <stdio.h>
#define SIZE 101
void swap(char* a, char* b);
int main(void)
{
char string1[SIZE]; char string2[SIZE];
printf("please enter string 1 :");
scanf("%s",string1);
printf("please enter string 2 :");
scanf("%s",string2);
swap(string1, string2);
printf("string 1 is %s, string 2 is %s\n",string1,string2);
return 0;
}
void swap(char* a, char* b)
{
int i; char temp[101];
for(i=0; i<SIZE; i++)
{
temp[i] = *(a+i);
*(a+i) = *(b+i);
*(b+i) = temp[i];
}
}

Related

How to count a specific character in an array and also call the function?

I am trying to make a program to count a specific character in an array. I got the program working how I think it should be working, however it was all in my main function and I wanted to break it out of there but I seem to be having an issue with doing so. My code when it was all in main was:
#include <stdio.h>
#include <stdlib.h>
int main(void)
{
char array[100];
int i = 0;
int a_counter = 0;
printf("Enter an array: \n");
scanf("%[^\n], array);
printf("Array is: %s\n", array);
for( i = 0; array[i] != '\0'; i++)
{
if (array[i] == 'A')
a_counter++;
}
printf("Number of A's: %d\n, a_counter);
}
In the code above, if I enter AAABCDEF, the result would tell me that there are 3 A's.
Now, I want to get this out of main and also not limit the character to only being an 'A'. I wanted to to count whatever character I set the function call with. My attempt to do so was this:
#include <stdio.h>
#include <stdlib.h>
int main(void)
{
char array[100];
printf("Enter an array: \n");
scanf("%[^\n], array);
printf("Array is: %s\n", array);
countletter(array, 'A');
countletter(array, 'L'); //I want to call function and add
//whatever letter I felt like it
return 0;
}
void countletter(char(array), char x)
{
int i = 0;
int count = 0;
for (i = 0; array[&i] != '\0'; i++)
if(array[&i] == x)
count++;
printf("Number of %c's: %d\n", x, count);
}
so if I called the countletter function, I wanted it to count the specific letter I sent it to count but my outputs were not even close. My outputs seemed to always be zero, and if I entered a specific array, it would put me in an infinite input mode. It seems that I am still confused on pointers and passing and calling functions.
The function you have written is wrong
void countletter(char *array, char x)
{
int i = 0;
int count = 0;
for (i = 0; array[i] != '\0'; i++)
if(array[i] == x)
count++;
printf("Number of %c's: %d\n", x, count);
}
Also before main, you have to declare the function
void countletter(char *array, char x);
Instead of defining
void countletter(char(array), char x)
{
int i = 0;
int count = 0;
for (i = 0; array[&i] != '\0'; i++)
if(array[&i] == x)
count++;
printf("Number of %c's: %d\n", x, count);
}
you should define:
void countletter(char array[], char x) // OR void countletter(char* array, char x)
{
int i = 0;
int count = 0;
for (i = 0; array[i] != '\0'; i++)
if(array[i] == x)
count++;
printf("Number of %c's: %d\n", x, count);
}
Moreover its a good practice to always pass size with an array or string. So probably below is the better function prototype.
void countletter(char array[], int size, char x)
There are two errors int he code:
void countletter(char(array), char x)
and
for (i = 0; array[&i] != '\0'; i++)
if(array[&i] == x)
The correct lines are:
void countletter(char* array, size_t size, char x)
and
for (i = 0; (i < size) && (array[i] != '\0'); i++)
if(array[i] == x)
You have to pass the entire array (by passing pointer to its first element in my example) and you have to work as usual (exactly as you did in the first monolithic version).
You must also pass the array size and take it into account when working with the array.
I would personally prefer this syntax for dealing with pointers.
void countLetter(char *array, char x) {...}
And for iterating through the array
for(i=0; *(array+i) != '\0'; i++)
Similarly for comparing
if(*(array+i) == x)
Internally, array[i] gets converted in *(array+i), so you can choose whatever you want.
The problem with your code is your method
countletter(char(array), char x)
This method is expecting two characters as parameters, where as you are passing a pointer and a character.
Second one is
array[&i]
For accessing ith element of an array, you should use something like array[i].

Print sorted strings from array of strings

I need help with the following program:
Print all sorted strings from the input array of strings.
Assume that strings are sorted if characters are in lexicographic order (also assume that the only characters in strings are letters).
Example:
INPUT:
n=2
1. string: stack
2. string: exchange
OUTPUT:
No sorted strings
I am having a problem with accessing some variables in the following program:
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#define MAX 30
char** read(int *pn);
int isSorted(char *str);
char** sortedArr(char **str,int pn);
char** read(int *pn)
{
do
{
printf("n = ");
scanf("%d",pn);
}
while(*pn < 1);
char **arr;
arr=(char **)malloc(*pn * sizeof(char *));
int i;
for(i=0; i<*pn;i++)
arr[i]=(char *)malloc(MAX+1);
for(i=0; i<*pn; i++)
{
printf("%d. word: ",i+1);
scanf("%s",arr[i]);
}
return arr;
}
int isSorted(char *str)
{
int i,j;
for(i=0; i<strlen(str)-1;i++)
for(j=i+1; j<strlen(str); j++)
if(strcmp(str+i,str+j) > 0)
return 1;
return 0;
}
char** sortedArr(char **str,int pn)
{
char **sortArr;
sortArr=(char **)malloc(pn * sizeof(char *));
int i;
for(i=0; i<pn; i++)
{
if(isSorted(sortArr[i]))
sortArr[i]=(char *)malloc(MAX+1);
}
for(i=0; i<pn; i++)
{
if(isSorted(sortArr[i]))
printf("%d. word: %s",sortArr+i);
}
return sortArr;
}
int main()
{
char **arr;
char **sortArr;
int pn;
arr=read(&pn);
sortArr=sortedArr(arr,pn);
int i;
for(i=0; i<pn; i++)
free(arr[i]);
free(arr);
return 0;
}
The problem is how to access the variable pn in function sortedArr()?
Your program has several issues, I'll try to address the most part of them.
Let's start from the isSorted function, if your goal is to check if a word has all the character sorted, you don't need to use strcmp or a nested loop. All what you need is something like this:
// check if all the character in the string are sorted
int isSorted( char *str )
{
int i, length = strlen(str) - 1;
for ( i=0; i < length; i++ )
if ( str[i] > str[i+1] )
return 0;
return 1;
}
I'll separate the printing function from the input one and copy ones, so to have:
void print( char **str, int n )
{
int i;
for ( i = 0; i < n; i++ ) {
printf("word %d: %s\n", i + 1, str[i]);
}
}
There are several methods to read some words from stdin and some are presented in other answers. I'll use this, but you should check all the pointers returned from malloc:
char** read(int *pn)
{
char buffer[BUFSIZE];
printf("Please, enter number of words: ");
while ( *pn < 1 && fgets(buffer, BUFSIZE, stdin) ) {
sscanf(buffer, "%d", pn);
}
int i = 0, length;
printf("\nPlease, enter the words: \n");
char **arr = malloc(*pn * sizeof(char *));
while ( i < *pn ) {
// read words one line at a time
if ( !fgets(buffer, BUFSIZE, stdin) )
break;
length = strlen(buffer);
// ignore empty lines
if ( length < 2 )
continue;
arr[i] = malloc(length);
memcpy(arr[i],buffer,length);
// add the null terminator
arr[i][length - 1] = '\0';
++i;
}
*pn = i;
return arr;
}
Then, I'm not really sure if you want only to print the words that are "sorted" or you actually need to copy them (and print later). I'll show you the latter:
// return an array of string containing only the sorted ones
char** sortedArr( char **str, int n, int *m)
{
char **sortArr = NULL;
char *sorted = calloc(n,1);
int i;
*m = 0;
// first find (and count) the sorted strings
for ( i = 0; i < n; i++ ) {
if ( isSorted(str[i]) ) {
// maybe you need only to print str[i] now...
sorted[i] = 1;
++(*m);
}
}
// then copy the sorted. I'm not sure if you need this
int j = 0, length = 0;
if ( *m ) {
sortArr = malloc(*m * sizeof(char *));
for ( i = 0; i < n; i++ ) {
if ( !sorted[i] )
continue;
length = strlen(str[i]) + 1;
sortArr[j] = malloc(length);
memcpy(sortArr[j],str[i],length);
}
}
free(sorted);
return sortArr;
}
Finally the main function (and the one to free allocated memory):
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#define BUFSIZE 128
char** read( int *pn );
int isSorted( char *str );
char** sortedArr( char **str, int n, int *m );
void print( char **str, int n );
void freeArr( char **str, int n );
void freeArr( char **str, int n )
{
if ( !str ) return;
int i;
for ( i = 0; i < n; i++ ) {
free(str[i]);
}
free(str);
}
int main()
{
char **arr = NULL;
char **sortArr = NULL;
int n = 0, m = 0;
arr = read(&n);
print(arr, n);
printf("\nSorted: \n");
sortArr = sortedArr(arr,n,&m);
print(sortArr, m);
freeArr(sortArr, m);
freeArr(arr, n);
return 0;
}
Hope it helped. Tell me if there is something wrong or I have misunderstood your task.
Change the sortedArr function, so that it takes pn as an argument:
char** sortedArr(char **str, int pn)...
Then, in your main(), change the sortArr=sortedArr(arr) to sortArr=sortedArr(arr, pn), to pass the value to the function. Then you can use the pn value inside the sortedArr function.
One head-scratcher is:
for(i=0; i<*pn;i++)
arr[i]=(char *)malloc(strlen(arr+i)+1);
for(i=0; i<*pn; i++)
{
printf("%d. word: ",i+1);
scanf("%s",arr[i]);
}
You should combine both because you cannot allocate properly until you know the length of word. Allocating some strlen(arr+i)+1 for who knows what is at arr+i is meaningless (and unless arr+i just happens to be a nul-terminated string, undefined behavior). When you are taking input, you can/should use a temprory buffer to hold the input until you can validate it is what you want it to be. At minimum, test the return to scanf to insure you actually had a sucessful conversion to the type of input you are expecting. For instance:
for (i = 0; i < *pn; i++)
{
char buf[64] = ""; /* however long is sufficient for word */
printf ("%d. word: ",i+1);
if (scanf ("%63[^\n']%*c",buf) == 1)
arr[i] = strdup (buf); /* allocates/copies buf for arr[i] */
else {
fprintf (stderr, "error: invalid input for word[%d].\n", i);
}
}
(note: you have similar allocation issues in sortedArr)
For your sort, you need to pass pn as a parameter to sortedArr so you at least know how many strings you are dealing with. Rather than looping and attempting to compare adjacent elements, why not have your sortedArr function simply call qsort and sort the array you create in read. If you want to preserve both the original and sorted arrays, then have sortedArr call memcpy and create a copy of arr and then call qsort on the copy. All you need to do is create a string comparison compare function for qsort to compare arr or the copy, e.g.:
/* comparison function for qsort (char **) */
int cmp_str (const void *a, const void *b)
{
/* The actual arguments to this function are "pointers to
pointers to char", but strcmp(3) arguments are "pointers
to char", hence the following cast plus dereference
note: to reverse sort order, swap a and b, below */
return strcmp (* (char * const *) a, * (char * const *) b);
}
Which you can then use to sort your arr (or copy) with
qsort (arr, pn, sizeof *arr, cmp_str);
Much less error-prone then a one-off loop and index attempt. Give it a try and let me know if you have questions.

C program for how to reverse a number explanation needed

While searching for a C program on how to reverse a string, i came across the below program. I am already familiar with a program where we take the length of the string and then minus each character and find the reverse. But this a different program. So can someone please tell me how this code works? Help will be gratefully accepted.
compiler used is Borland Turbo c.
#include<stdio.h>
#include<conio.h>
#include<string.h>
void main() {
char str[50];
char rev[50];
int i, j, n;
clrscr();
printf("enter the string to be reversed:");
scanf("%s", &str);
for (i = 0; str[i] != 0; i++) {
n = i - 1;
}
for (j = 0; j <= i - 1; j++) {
rev[j] = str[i];
n--;
}
printf("the reverse of the string is:%s", rev);
getch();
}
In C, strings are NUL-terminated meaning that it has '\0' at the end signifying the end of the string. The code you've posted currently has two issues:
This:
scanf("%s", &str);
should be
scanf("%s", str);
as %s expects a char*, not a char(*)[50].
This:
rev[j] = str[i];
should be
rev[j] = str[n];
rev should be NUL-terminated before printing. Add
rev[j] = '\0';
just before
printf("the reverse of the string is:%s", rev);
to avoid Undefined Behavior.
Your code doesn't work as it is supposed to.Have you tried it ?
Consider this approach to reverse a string :
#include <stdio.h>
#include <string.h>
int reverse(char *Str);
void swap(char *x, char *y);
int main(int argc, char *argv[]) {
char Str[255];
printf("enter the string to be reversed : ");
scanf("%s", Str);
reverse(Str);
printf("the reverse of the string is : %s\n", Str);
}
int reverse(char *Str) {
size_t len = strlen(Str);
size_t n = len / 2;
char *begin = Str;
char *end = (Str + len) - 1;
while (n > 0) {
swap(begin, end);
begin++;
end--;
n--;
}
return 0;
}
void swap(char *x, char *y) {
char tmp;
tmp = *x;
*x = *y;
*y = tmp;
}

C Double pointer Char is printing NULL. Don't Know what's going wrong?

This is display function to display the strings read in.
void print(char **s,int T)
{
while(*s)
{
printf("i: String : %s\n",*s++);
}
}
int main()
{
int T =0,i=0;
char ** s, *c;
printf("Enter number of Testcases:\n");
scanf("%d",&T);
s = (char **)malloc(T*sizeof(char *));
printf("Size allocated : %lu\n",sizeof(s));
while(i++ < T)
{
s= (char *)malloc(10000*sizeof(char));
scanf("%s",*s++);
}
print(s,T);
return 0;
}
This code:
s= (char *)malloc(10000*sizeof(char));
scanf("%s", *s++);
should be:
s[i-1] = malloc(10000);
scanf("%9999s", s[i-1];
I would advise to refactor the loop so that you use i within the loop rather than i-1.
Your original idea doesn't work because:
you wrote s instead of *s in the malloc
once this loop finishes, s points to the end of the list; but you then pass s to your print function which is expecting a pointer to the start of the list
Further, the print function currently iterates off the end of the array (if you pass s correctly as I suggest above, that is). Instead, it should stop after it has printed T strings. You should probably change the call to print(s, i); ; update print to loop based on that int, and also add a check for scanf failure.
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
void print(char **s,int T){
int i=0;
while(T--){
printf("%d: String : %s\n", ++i, *s++);
}
}
int main(){
int T =0, i=0;
char **s, **p;
size_t size;
printf("Enter number of Testcases:\n");
scanf("%d",&T);
p = s = (char **)malloc(size=T*sizeof(char *));
//printf("Size allocated : %zu\n", size);
printf("Size allocated : %lu\n", (unsigned long)size);
while(i++ < T){
char tmp[10000];
scanf("%9999s", tmp);
*p++ = strdup(tmp);//strdup is not standard function
}
print(s,T);
//deallocate
return 0;
}

Reverse char array with pointer in C

I want to reverse a char array using pointers, but all I get when I printf the pointer is null. I don't know what I'm doing wrong or how to fix it. So how can I reverse the string in a similar way?
#include <stdio.h>
void reverse(char *cstr);
int main()
{
char a[100];
char *p = a;
printf("geef een string "); // ask user to write a word
scanf("%s", &a);
reverse(p);
printf("%s", *p);
}
void reverse(char *p)
{
int i = 0;
char temp;
int lengte;
for(i = 0; *(p+i) != '\0'; i++)
{
lengte++; // length of char array without the '\0'
}
for(i = 0; i < lengte; i++)
{
temp = p[i]; // something goes wrong here but I don't know what
p[i] = p[lengte-i];
p[lengte-i] = tem;
}
}
Something goes wrong at the
p[i] = p[lengte-i];
p[lengte-i] = tem;
part. What do I need to change it to?
Two adjustments:
replace
printf("%s", *p);
with
printf("%s", p);
because printf is expecting a pointer, not a dereferenced pointer,
and
for(i = 0; i < lengte; i++)
with
for(i = 0; i < lengte--; i++)
because your counting of the length in the loop before that one ends up with one char too many. Hence the \0 is placed at the beginning of the string.
$ gcc test.c && ./a.out
geef een string 1234
4231$

Resources