Shuffle characters in an array in C programming - c

Using an online tutorial I worked on trying to shuffle characters in an array. The tutorial I used was using integers and also didn't include any user input, but when I try and replicate it and change it to do what I would like in the code I made below something is not working out.
There is no error message at all. When I run the program it only prompts the user to enter a word and then ends.
Just in case you can't understand what I wanted from the code I would like the user to be able to insert a word and then the 'shuffled' word is printed at the end. (ex. Hello > elHol)
I am still a very new programmer and have a very hard time with the subject in general so please understand any 'dumb' mistakes you'll likely come across that I've made.
Thanks in advance for any help!
#include <stdio.h>
#include <time.h>
int main ()
{
char word[15];
int i,length,j, temp;
srand(time(NULL));
printf("Insert word\n");
scanf("%s", word);
for(i=0; word[i] != '\0'; )
{
i = i + 1;
}
i = length;
for(i = 0; i < length; i++)
{
j = (rand()%length);
temp = word[i];
word[i] = word[j];
word[j] = temp;
}
for(i=0; i<length; i++)
{
printf("%c", word[i]);
}
}

Welcome ;). In addition to the other engineers's solution to your problem, I have modified your code not to use the temporary variable to swap.[ since you mentioned new programmer, i felt this should help to some extend. ;) ]
Look at the below source code.
#include <stdio.h>
#include <time.h>
#include <stdlib.h>
int main ()
{
char word[15];
int i,length,j, temp;
srand(time(NULL));
printf("Insert word\n");
scanf("%s", word);
for(length=0; word[length++] != '\0';);
for(i = 0; i < length; i++)
{
j = (rand()%length);
word[i] = word[i] ^ word[j];
word[j] = word[i] ^ word[j];
word[i] = word[i] ^ word[j];
}
for(i=0; i<length; i++)
{
printf("%c", word[i]);
}
}

Few changes to your code:
Make temp as char :
char temp;
Assign length to i you are doing it the other way where you are assigning i to length and since length is uninitialized and you are using it this value to assign to some other variable causes undefined behavior.
length = i;

Try my revision of your code!
This will fix the spaces and lost of vowels in printing the shuffle string. SORRY FOR MY BAD ENLISH :)
#include<stdio.h>
#include<stdlib.h>
int main(){
char word[100];
srand(time(NULL));
int i,j,length,temp;
printf("Enter a string: ");
scanf("%s",&word);
for(i = 0; word[i] != '\0'; ++i){
length = i;
}
length+=1;
i = length;
while(--i>0){
j = (rand()%length);
temp= word[j];
word[j]= word[i];
word[i]= temp;
}
for(i=0; i<=length; i++)
{
printf("%c", word[i]);
}
}

Related

Function with two parameters removes all spaces from string

I'm learning C and I've a problem with this school homework.
I have to make function which get two strings from user as parameters. The function removes all spaces from the first string and returns the "cleaned" strings as the other parameter.
The main function ask three strings, uses function to remove spaces and prints "cleaned" strings.
My code doesn't work as it should? What goes wrong?
#include <stdio.h>
void removeSpaces(char *, char *);
int main(){
int i, j;
char string[101], strings[1][101];
for(i = 0; i <= 2; i++){
fgets(string, 100, stdin);
for(j = 0; string[j] != '\0'; j++){
strings[i][j] = string[j];
}
strings[i][j] = '\0';
removeSpaces(strings[i], strings[i]);
}
for(i = 0; i <= 0; i++){
for(j = 0; j <= 101; j++){
printf("%c", strings[i][j]);
}
}
}
void removeSpaces(char *string1, char *string2){
int i, j;
for(i = 0; string1[i] != '\0'; i++){
if(string1[i] != ' '){
string2[i] = string1[j];
j++;
}
}
string2[i] = '\0';
}
You have to be more careful when writing code. There are several things wrong:
In removeSpaces(), you never initialize j. So it can be anything.
You are also mixing up i and j inside removeSpaces(). i should only be used to index string1, and j only for string2.
strings[1][101] is only one string, not 3. But the first for-loop in main() runs 3 times.
You don't have to print strings character by character, just printf("%s", strings[i]) or fputs(strings[i], stdout).
I'm not sure why you used a two-dimensional array strings here. You only need two strings. Renaming the variables can also help you avoid getting confused. Consider:
#include <stdio.h>
static void removeSpaces(const char *input, char *output) {
int i, o;
for(i = 0, o = 0; input[i] != '\0'; i++) {
if(input[i] != ' ') {
output[o] = input[i];
o++;
}
}
output[o] = '\0';
}
int main() {
char input[100], output[100];
fgets(input, sizeof input, stdin);
removeSpaces(input, output);
fputs(output, stdout);
}

Checking whether string is palindrome or not using Functions in C

I want to check whether a string entered by the user is palindrome or not. Without using functions I have done this problem but when I use functions for this problem I am always getting the same output:
The Entered String Is Not Palindrome!
Even if the string entered by the user is palindrome I get the same output. Here is my code:
#include <stdio.h>
#include <string.h>
void reverse(char [],int);
int main() {
char a[100];int len, i = 0;
printf("Please enter the string to check: \n");
fgets(a,100,stdin);
//Loop to replace the '\n' inserted at the end of string due to fgets() with '\0'
for (int i = 0; i < strlen(a); ++i)
{
if (a[i] == '\n')
{
a[i] = '\0';
}
}
len = strlen(a);
reverse(a,len);
return 0;
}
void reverse(char b[100], int n) {
char c[100];int k=0;
//Read characters from b[] from the end and store them into c[]
for (int i = n-1; i >= 0; i--)
{
c[k] +=b[i];
k++;
}
c[k] = '\0';
//Check if the reversed string c[] and the actual string b[] are equal
if(strcmp(c,b) == 0)
printf("The Entered String Is Palindrome!\n");
else
printf("The Entered String Is Not Palindrome!\n");
}
The code in the reverse() function is the same as the one I used to solve the same problem without functions(and that program worked perfectly fine). But still it isn't giving the correct output. What am I doing wrong here?
EDIT: Okay, so I have removed the c[k] += b[i] according to an users suggestion and now it works perfectly fine. But I still don't get it. I mean I used the same line in the same program, the only difference being I didn't use the functions concept there and it worked perfectly fine. Here is the code:
#include <stdio.h>
#include <string.h>
int main() {
char a[100], b[100];
int k=0;
printf("Please enter the string: \n");
fgets(a,100,stdin);
//To replace the '\n' at the end of the string inserted by fgets()
for (int i = 0; i < strlen(a); ++i)
{
if(a[i] == '\n')
a[i] = '\0';
}
for (int i = strlen(a)-1; i >=0 ; i--)
{
b[k] += a[i];
k++;
}
if (strcmp(a,b) == 0)
{
printf("The entered string is palindrome!\n");
}
else
printf("The entered string is not palindrome! \n");
return 0;
}
Is there some concept behind it that I am unaware of? If so then please enlighten me.
You invoked undefined behavior by using values of an uninitialized variable having automatic storage duration, which is indeterminate.
Instead of adding in c[k] +=b[i];, just assign value from b as c[k] = b[i];.

Garbled string output

I'm currently working on an assignment which asks me to censor words of argv and input redirection.
My problem is obvious in my output which can be found below. I have a lot of tracing print statements which may or may not help you point out my issue.
My intention is:
Get file.txt
Copy contents of file.txt into buffer[x][y], where [x] is a string of word and [y] is a char of [x].
Compare argv[] arguments to buffer[][].
Create newstr[size2]. For every argv[] arguement found in buffer[][], replace it with replace[9] = "CENSORED".
Print the string of newstr[0 to (size2-1)].
Here is my code:
// censored.c
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <ctype.h>
#define SIZE 128
int main ( int argc, char* argv[])
{
int i = 0;
int j = 0;
int k = 0;
char buffer[SIZE][SIZE];
char x;
int count = 0;
int size1 = sizeof(buffer);
int size2 = 0;
char replace[9] = "CENSORED";
int buffersize=0;
printf("tracing: size1: %d.\n", size1);
printf("tracing: argc: %d.\n", argc);
while((fscanf(stdin, "%c", &x)!=EOF))
{
if(isalpha(x))
{
buffer[i][j]=x;
printf("tracing: buffer[%d][%d]: %c\n", i,j, buffer[i][j]);
j++;
}
else if(isspace(x)) // if whitespace
{
j = 0;
i++;
buffer[i][j]=x;//this should be buffer[i][j]
printf("tracing: buffer[%d][%d]: %c\n", i,j, buffer[i][j]);
j = 0;
i++;
}
else if(ispunct(x)) // if x is a punctuation
{
j = 0;
i++;
buffer[i][j]=x;//this should be buffer[i][j]
printf("tracing: buffer[%d][%d]: %c\n", i,j, buffer[i][j]);
}
else if(iscntrl(x)) // if control key (\n, \r etc...)
{
j = 0;
i++;
buffer[i][j]=x;//this should be buffer[i][j]
printf("tracing: buffer[%d][%d]: %c", i,j, buffer[i][j]);
j = 0;
i++;
}
else if(isdigit(x))
{
buffer[i][j]=x;//this should be buffer[i][j]
printf("tracing: buffer[%d][%d]: %c\n", i,j, buffer[i][j]);
j++;
}
else
{
break;
}
}
size2 = i;
printf("tracing: buffer[8][0]:%s\n",buffer[8]);
char newstr[size2][SIZE];
i = 0;
j = 0;
// tracing:
printf("tracing: line 72\n");
printf("tracing: size2: %d.\n", size2);
while(i < size2) //print buffer[]
{
printf("%s", buffer[i]);
i++;
}
printf("tracing: line 80\n");
for(k=1; k < argc; k++)
{
printf("%s\n", argv[k]);
}
// end tracing
i = 0; //reinitialize i
j = 0; //reinitialize j
// creating newstr[SIZE] and censoring words
printf("tracing: line 89\n");
for(i = 0; i < size2; i++)
{
for(j=1; j < argc; j++)
{
if(strcmp(buffer[i], argv[j])==0)
{
strcpy(newstr[i], &replace[0]);
printf("tracing: replaced at [%d]\n", i);
break;
}
else
{
strcpy(newstr[i], buffer[i]);
printf("tracing: copied at [%d]\n", i);
}
}
}
i = 0; //reinitialize i
while(i < size2)
{
printf("%s", newstr[i]);
i++;
}
return 0;
}
Assuming I have input redirection file named file.txt and its contents:
Said Hamlet to Ophelia,
I'll draw a sketch of thee,
What kind of pencil shall I use?
2B or not 2B?
my input is:
./censored Ophelia thee 2B < file.txt
this is the weird output I got:
Said Hamlet to CENSORED, Ill draw a sketch ???)ofoQ? ?"h?CENSORED,2oQ?
What? /oQ?kind? of 6oQ?pencil +oQ?shall ?"h?I-oQ? ???)use? ???2BoQ?
7oQoroQ Qnot 1oQ?CENSORED?4oQ?
Any help is appreciated, I know my code is messy, this is my first semester learning C.
I have good and bad news, the bad one is: I found a few errors and mistake.
The good one is: all of these are common for a beginner!
First one: The strings in buffer[] aren't terminated with a '\0' which is the end of string indicator. This is the one cause of your problem.
And here are the other ones:
char buffer[SIZE][SIZE];
Here you are considering that number of words and word's length can't be longer that 128 which will cause Segmentation Fault whenever this condition is wrong. I suggest you learn about dynamic allocation (malloc()).
for(j=1; j < argc; j++) If argc == 1, you won't enter this loop which would result in newstr being empty. Usually we end arrays with a NULL pointer and then check for every string of the array being non-null while reading the array so that we won't try to use undefined content.
As you pointed at, your code is quite messy, next time, try separating your code in functions and not coding in main().
Try reducing this, the fewer lines your write, the easier your code is to read and debug:
j = 0;
i++;
buffer[i][j]=x;//this should be buffer[i][j]
printf("tracing: buffer[%d][%d]: %c\n", i,j, buffer[i][j]);
j = 0;
i++;
This advice isn't really relevant for that kind of program designed to read a lot of data but remember: try to avoid storing data whenever you can.
I think this is enough for now, I wish you good luck and to apologize for my poor English.

Getting most frequent characters in array in c

I am trying to get the most frequent characters from an array.
Here's my code
#include <stdio.h>
int main(void)
{
int c[1000];
char input[] = "abcdab";
int i;
for(i=0; input[i]; i++)
{
c[input[i]]++;
}
int j = 0;
char str = 0;
for(i=0; i<256; i++)
{
if(c[i] > j)
{
j = c[i];
str = i;
}
}
printf("%c\n", str);
return 0;
}
It returns 'a'
But I want to get 'a' and 'b' since they are the most frequent characters in the array.
Any help would be appreciated, thank you.
You are passing through the entire array looking for a maximum, and remembering the first one. With the solution you have, you need an additional loop:
for(i=0; i<256; i++){ // Look for all maximums
if(c[i] == j) // If it is the maximum
{
printf("%c\n", i); // print the character
}
}
Note that your array c is not initialized to all zeroes, so it is purely by chance (not really) that the code is working. If you want c to be all zeroes, you need to declare it as int c[1000] = {0}; or to call memset on it.

Printing Array of Strings

I'm parsing a text file:
Hello, this is a text file.
and creating by turning the file into a char[]. Now I want to take the array, iterate through it, and create an array of arrays that splits the file into words:
string[0] = Hello
string[1] = this
string[2] = is
This is my code:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "TextReader.h"
#include <ctype.h>
void printWord(char *string) {
int i;
for (i = 0; i < strlen(string); i ++)
printf("%c", string[i]);
printf("\n");
}
void getWord(char *string) {
char sentences[5][4];
int i;
int letter_counter = 0;
int word_counter = 0;
for (i = 0; i < strlen(string); i ++) {
// Checks if the character is a letter
if (isalpha(string[i])) {
sentences[word_counter][letter_counter] = string[i];
letter_counter++;
} else {
sentences[word_counter][letter_counter + 1] = '\0';
word_counter++;
letter_counter = 0;
}
}
// This is the code to see what it returns:
i = 0;
for (i; i < 5; i ++) {
int a = 0;
for (a; a < 4; a++) {
printf("%c", sentences[i][a]);
}
printf("\n");
}
}
int main() {
// This just returns the character array. No errors or problems here.
char *string = readFile("test.txt");
getWord(string);
return 0;
}
This is what it returns:
Hell
o
this
is
a) w
I suspect this has something to do with pointers and stuff. I come from a strong Java background so I'm still getting used to C.
With sentences[5][4] you're limiting the number of sentences to 5 and the length of each word to 4. You'll need to make it bigger in order to process more and longer words. Try sentences[10][10]. You're also not checking if your input words aren't longer than what sentences can handle. With bigger inputs this can lead to heap-overflows & acces violations, remember that C does not check your pointers for you!
Of course, if you're going to use this method for bigger files with bigger words you'll need to make it bigger or allocate it dymanically.
sample that do not use strtok:
void getWord(char *string){
char buff[32];
int letter_counter = 0;
int word_counter = 0;
int i=0;
char ch;
while(!isalpha(string[i]))++i;//skip
while(ch=string[i]){
if(isalpha(ch)){
buff[letter_counter++] = ch;
++i;
} else {
buff[letter_counter] = '\0';
printf("string[%d] = %s\n", word_counter++, buff);//copy to dynamic allocate array
letter_counter = 0;
while(string[++i] && !isalpha(string[i]));//skip
}
}
}
use strtok version:
void getWord(const char *string){
char buff[1024];//Unnecessary if possible change
char *p;
int word_counter = 0;
strcpy(buff, string);
for(p=buff;NULL!=(p=strtok(p, " ,."));p=NULL){//delimiter != (not isaplha(ch))
printf("string[%d] = %s\n", word_counter++, p);//copy to dynamic allocate array
}
}

Resources