my program does not compile. It keeps on saying:
[ERROR] invalid conversion from 'char' to 'char*'
It should be a program that identifies if two strings are an anagram of each other.
I used a sorting method but i don't know if it will work.
Hope you guys could help me out.
P.S I can only use strings and arrays.
int main ()
{
char sString_1[100], sString2[100], store[50];
int j, i;
printf("Enter String 1: ");
gets(sString_1);
printf("\nEnter String 2: ");
gets(sString2);
if (strlen(sString_1) != strlen(sString2))
printf("%s and %s are not anagrams", sString_1, sString2);
else
{
for(i = 0; i < strlen(sString_1); ++i)
{
for (j=i+1 ; j <= strlen(sString_1); ++j)
{
if (strcmp(sString_1[i], sString2[j]) > 0)
{
strcpy(store,sString_1[i]);
strcpy(sString_1[i],sString_1[j]);
strcpy(sString_1[j],store);
}
}
}
for(i = 0; i < strlen(sString2); i++)
{
for (j= i + 1; j <= strlen(sString2); j++)
{
if (strcmp(sString2[i], sString2[j]) >0)
{
strcpy(store,sString2[i]);
strcpy(sString2[i],sString2[j]);
strcpy(sString2[j],store);
}
}
}
if (strcmp(sString_1, sString2) == 0)
printf("ANAGRAM");
else
printf("NOT");
}
}
strcmp(sString_1[i], sString2[j])
The arguments to strcmp shoud be of type const char *, yet you pass single chars.
In general when you use p[i] then you are changing the pointer (or array) p into what it points to, e.g. a character.
It is like writing *(p+i). To get the address of that character you can either write p+i or &p[i].
Example: to fix the errors you have to change
strcmp(sString_1[i], sString2[j])
into
strcmp(&sString_1[i], &sString2[j])
Do you want to make like this?
char sString_1[100], sString2[100], store; // store is 1char
//=======omit==========
else
{
for(i = 0; i < strlen(sString_1); ++i)
{
for (j=i+1 ; j < strlen(sString_1); ++j) // "<="→"<"
{
if (sString_1[i] > sString2[j]) // char
{
store = sString_1[i]; // char
sString_1[i] = sString_1[j];
sString_1[j] = store;
}
}
}
for(i = 0; i < strlen(sString2); i++)
{
for (j= i + 1; j < strlen(sString2); j++) // "<="→"<"
{
if (sString2[i] > sString2[j]) // char
{
store = sString2[i]; // char
sString2[i] = sString2[j];
sString2[j] = store;
}
}
}
//=======omit==========
1 loop
4250
2450
0452
2 loop
0254
3 loop
0245
Related
I want to remove all the repeated characters from array. here is example.
"aabccdee"
"bd"
I'm doing this C language. use only array, loop, if,else(conditional statements) not using pointer.
#include<stdio.h>
int main() {
char c[10];
char com[10] = {0,};
char result[10] = { 0, };
int cnt = 0;
for (int i = 0; i < 10; i++) {
scanf("%c", &c[i]);
}
for (int i = 0; i < 10; i++) {
for (int j = i+1; j < 10; j++) {
if (c[i] == c[j]) {
com[i] = c[i];
cnt++;
printf("%c", com[i]);
}
}
}
for (int i = 0; i < cnt; i++) {
for (int j = 0; j < 10; j++) {
if (com[i] != c[j]) {
result[j] = c[j];
}
}
}
printf("\n");
for (int i = 0; i < 10; i++) {
printf("%c", result[i]);
}
}
I thought this
Make repeated array
Compare original array to repeated array
Output
But repeated array loop can't looping all original array.
How can I do remove all repeated character?
Not good SO policy to blatantly answer homework, but I rarely do it and thought this was an interesting task. Certainly making no claims on efficiency, but it looks like it works to me. As far as I can tell, the first and last cases are corner cases, so I handle those individually, and use a loop for everything in the middle. If you're not allowed to use strlen, then you can roll your own or use some other method, that's not the primary focus of this problem (would be best to fgets the string from a command line argument).
#include <stdio.h>
#include <string.h>
int main(void)
{
char source[] = "aabccdee";
char result[sizeof(source)] = { 0 };
unsigned resultIndex = 0;
unsigned i = 0;
// do this to avoid accessing out of bounds of source.
if (strlen(source) > 1)
{
// handle the first case, compare index 0 to index 1. If they're unequal, save
// index 0.
if (source[i] != source[i+1])
{
result[resultIndex++] = source[i];
}
// source[0] has already been checked, increment i to 1.
i++;
// comparing to strlen(source) - 1 because in this loop we are comparing the
// previous and next characters to the current. Looping from 1 to second-to-the-
// last char means we stay in bounds of source
for ( ; i < strlen(source) - 1; i++)
{
if (source[i-1] != source[i] && source[i] != source[i+1])
{
// write to result if curr char != prev char AND curr char != next char
result[resultIndex++] = source[i];
}
}
// handle the end. At this point, i == the last index of the string. Compare to
// previous character. If they're not equal, save the last character.
//
if (source[i] != source[i-1])
{
result[resultIndex] = source[i];
}
}
else if (strlen(source) == 1)
{
// if source is only 1 character, then it's trivial
result[resultIndex] = source[i];
}
else
{
// source has no length
fprintf(stderr, "source has no length.\n");
return -1;
}
// print source and result
printf("source = %s\n", source);
printf("result = %s\n", result);
return 0;
}
Various outputs for source:
source = "aabccdee"
result = "bd"
source = "aaee"
result =
source = "a"
result = "a"
source = "abcde"
result = "abcde"
source = "abcdee"
result = "abcd"
source = "aabcde"
result = "bcde"
source = "aaaaaaaaaaaabdeeeeeeee"
result = "bd"
source = ""
source has no length.
first of all before we speak , you have to check this
you need to put a whitespace when scaning a char using scanf
so
scanf("%c", &c[i]);
becomes
scanf(" %c", &c[i]);
secondly your idea is kinda a messy as the result showed you're only handling cases and it doesn't continue verifying the whole array . you need to learn how to shift an array to the right or left
your issue later on that when you shift your table(not completely) you still print out of the size .
so bascilly in general your code should be something like this :
#include<stdio.h>
int main() {
char c[10];
int length=5;
for (int i = 0; i < 5; i++) {
scanf(" %c", &c[i]);
}
int j,k,i;
for(i=0; i<length; i++)
{
for(j=i+1; j<length; j++)
{
if(c[i] == c[j])
{
length--;
for(k=j; k<length; k++)
{
c[k] = c[k + 1];
}
j--;
}
}
}
printf("\n");
for (int i = 0; i < length; i++) {
printf("%c", c[i]);
}
}
you simply take one case and compare it to the rest , if it exists you shift from the position you find for the second time the element and so on
I'm trying to sort a case sensitive array of words words[number of words][number of letters] alphabetically by strcmp using case insensitive array with same words. When I sort case insensitive array using case insensitive array and print it, it works, but if I try to sort case sensitive array using case insensitive array - it does not. Below are the blocks of code I am using to do this.
char cs_sns[20][20];
///scan here as you wish/////
char cs_ins[20][20];
for(int i = 0; i < 20; i++)
{
strcpy(cs_ins[i], cs_sns[i]);
}
//////////////////CONVERT///////////////////////////
for(int i = 0; i < 20; i++)
{
strlwr(cs_ins[i]);
}
/////////////////SORT_CASE_SENSITIVE_BY_LOWERCASE/////////////////////
for (int j = 0; j < 20; j++)
{
for (int i = 0; i < 20-1; i++)
{
int x = (strcmp(cs_ins[i], cs_ins[i+1]) > 0);
if (x == 1)
{
char temp[20];
strcpy(temp, cs_sns[i]);
strcpy(cs_sns[i], cs_sns[i+1]);
strcpy(cs_sns[i+1], temp);
}
}
}
/////////////////////SORT_LOWERCASE_BY_LOWERCASE/////////////////
for (int j = 0; j < 20; j++)
{
for (int i = 0; i < 20 - 1; i++)
{
int x = (strcmp(cs_ins[i], cs_ins[i+1]) > 0);
if (x == 1)
{
char temp[20];
strcpy(temp, cs_ins[i]);
strcpy(cs_ins[i], cs_ins[i+1]);
strcpy(cs_ins[i+1], temp);
}
}
}
///////////////PRINT/////////////////
for (int i = 0; i < 20; i++)
{
printf("%s\n", cs_sns[i]); //////////swap with cs_ins[i] and see what happens
}
Below is the stolen function strlwr to convert to lowercase.
///////////define strlwr/////////////////////
char *strlwr(char *str)
{
unsigned char *p = (unsigned char *)str;
while (*p)
{
*p = tolower((unsigned char)*p);
p++;
}
return str;
}
You'll need to include ctype.h for tolower.
What is it that I am missing?
Thank you.
Edit: Can be solved by stricmp, here is a link:
C99 remove stricmp() and strnicmp()?
Still curious tho...
The problem occurs because you are trying to sort your case-sensitive array according to the case-insensitive array, while NOT CHANGING the insensitive array.
This may work:
/////////////////SORT_CASE_SENSITIVE_BY_LOWERCASE/////////////////////
for (int j = 0; j < 20; j++)
{
for (int i = 0; i < 20-1; i++)
{
int x = (strcmp(cs_ins[i], cs_ins[i+1]) > 0);
if (x == 1)
{
char temp[20];
strcpy(temp, cs_sns[i]);
strcpy(cs_sns[i], cs_sns[i+1]);
strcpy(cs_sns[i+1], temp);
//swap elements in cs_ins[] as well
strcpy(temp, cs_ins[i]);
strcpy(cs_ins[i], cs_ins[i+1]);
strcpy(cs_ins[i+1], temp);
}
}
}
Thus applying the changes to the insensitive array as well.
Of course, just using stricmp would be a much simpler solution, as Monica has stated.
I am in the process of creating hangman in C language, but there is one problem that I cannot quite grasp. When a user correctly guesses one of the letters that the word that is being guessed has, the program replaces all of previously guessed letters to the one user just put. What is the source of this problem?
#include<stdio.h>
#include <stdlib.h>
int main()
{
srand(time(NULL));
int x = 0, isCompleted, matchFound, numberOfTries = 7;
char letterGuess[1];
int randomIndex = rand()%14;
const char *wordArray[14];
const char *guessedWord[10];
const char *usedLetters[17];
for (int k = 0; k < 10; k++) {
guessedWord[k] = "_";
}
wordArray[0] = "butonierka";
wordArray[1] = "centyfolia";
wordArray[2] = "chiroplast";
wordArray[3] = "cmentarzyk";
wordArray[4] = "chrustniak";
wordArray[5] = "budowniczy";
wordArray[6] = "cholewkarz";
wordArray[7] = "cornflakes";
wordArray[8] = "brzydactwo";
wordArray[9] = "germanofil";
wordArray[10] = "lichtarzyk";
wordArray[11] = "lutowniczy";
wordArray[12] = "mikrocysta";
wordArray[13] = "tryskawiec";
const char *wordToGuess = wordArray[randomIndex];
for(int i = 0; i < 10; i++) {
printf(" %s ", guessedWord[i]);
}
printf("\n");
while(numberOfTries != 0 && isCompleted != 10) {
matchFound = 0;
isCompleted = 0;
printf("Please give a lowercase letter\n");
printf("Left tries: %d\n", numberOfTries);
scanf("%s", &letterGuess);
for (int z = 0; z < 17; z++) {
if (usedLetters[z] == letterGuess[0]) {
matchFound = 1;
}
}
if (letterGuess[0] >= 'a' && letterGuess[0] <= 'z' && matchFound == 0) {
usedLetters[x] = letterGuess[0];
x++;
for (int j = 0; j < 10; j++) {
if (letterGuess[0] == wordArray[randomIndex][j])
guessedWord[j] = letterGuess;
matchFound = 1;
}
}
if (matchFound == 0) {
numberOfTries--;
}
for(int z = 0; z < 10; z++) {
printf(" %s ", guessedWord[z]);
}
printf("\n");
} else {
if (matchFound == 1) {
printf("You've already given such letter!!\n");
} else {
printf("Wrong input, please try again!\n");
}
}
for (int k = 0; k < 10; k++) {
if (guessedWord[k] != "_") {
isCompleted++;
}
}
if (isCompleted == 10) {
printf("You have correctly guessed a word! Congrats!!\n");
}
printf("\n\n");
}
printf("The word was: %s\n", wordArray[randomIndex]);
printf("Game over!!\n");
}
The problem is that you're storing letterGuess, rather than individual characters. So each time letterGuess is updated with a new guess, all references to it change. Also, letterGuess is too short, leaving no room for the terminating null character.
The best solution is to make letterGuess a char (or an int), not an array, and to make guessedWord a char [] rather than a char *[]. There is no reason to use strings for single characters. That will solve the string-sharing problem.
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 6 years ago.
Improve this question
I tried to do a code that gets number from the user and create array of strings (char**) by the number but for some reason it didn't work and the code crashed. After inputting the strings, the code sorts the strings using strcmp() and then I want to print the whole array. Could anyone help me?
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define LENGTH 20
int main(void)
{
int players = 0,i=0,j=0;
char switchString[LENGTH];
printf("Hello user, Welcome to your basketball team!\nplease enter a number of players that plays in your team\n");
scanf("%d", &players);
char** team = (char**)malloc(players*sizeof(char));
for (i = 0; i < players; i++)
{
*(team+i) = (char*)malloc(LENGTH*sizeof(char));
printf("enter name of player %d\n",i+1);
fgets(*(team+i), LENGTH, stdin);
*(team+i)[strcspn(*(team+i), "\n")] = "\0";
}
for (i = 0; i <players; i++)
{
for (j = 0; j < players; j++)
{
if (strcmp(team[j - 1], team[j]) > 0)
{
strcpy(switchString, team[j-1]);
strcpy(team[j-1], team[j]);
strcpy(team[j], switchString);
}
}
}
for (i = 0; i <players; i++)
{
for (j = 0; j < players; j++)
{
printf("%c",team[i][j]);
}
printf("\n");
}
system("PAUSE");
free(team);
return 0;
}
This memory allocation
char** team = (char**)malloc(players*sizeof(char));
^^^^^^^^^^^^
is wrong. There shall be
char** team = (char**)malloc(players*sizeof(char *));
^^^^^^^^^^^^^^
This assignment
*(team+i)[strcspn(*(team+i), "\n")] = "\0";
^^^^^^^^^ ^^^^
is also wrong
There shall be
( *(team+i) )[strcspn(*(team+i), "\n")] = '\0';
^^^^^^^^^^^^^ ^^^^
Or you could just write
team[i][strcspn(team[i], "\n")] = '\0';
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ ^^^^
Also this loop
for (j = 0; j < players; j++)
{
if (strcmp(team[j - 1], team[j]) > 0)
{
strcpy(switchString, team[j-1]);
strcpy(team[j-1], team[j]);
strcpy(team[j], switchString);
}
}
also incorrect because when j is equal to 0 then in the if statement in expression team[j - 1] there is an attempt to access memory beyond the array.
The loop should look at least like
for (j = 1; j < players; j++)
^^^^^
{
if (strcmp(team[j - 1], team[j]) > 0)
{
strcpy(switchString, team[j-1]);
strcpy(team[j-1], team[j]);
strcpy(team[j], switchString);
}
}
And at last these loops are also nvalid
for (i = 0; i <players; i++)
{
for (j = 0; j < players; j++)
{
printf("%c",team[i][j]);
}
printf("\n");
}
because in the inner loop there are attempts to output characters after the terminating zero.
Just write
for (i = 0; i <players; i++)
{
puts( team[i] );
}
Or you could write for example
for (i = 0; i <players; i++)
{
for (j = 0; players[i][j] != '\0'; j++)
{
printf("%c",team[i][j]);
}
printf("\n");
}
And at the end of the program you need to free the allocated memory.
For example
for (i = 0; i <players; i++)
{
free( team[i] );
}
free( team );
char** team = (char**)malloc(players*sizeof(char));
(Allocate memory of players bytes)
Should be
char** team = malloc(players*sizeof(char*));
(Allocate memory to store players pointers to character)
Replace line
char** team = (char**)malloc(players*sizeof(char));
with
char** team = malloc(players*sizeof(char*));
int i;
for (i = 0; i < players; i++)
team[i] = malloc(LENGTH*sizeof(char));
Assuming you have fixed the memory allocation for the main array of pointers, then the test in the inner loop like this:
if (strcmp(team[j - 1], team[j]) > 0)
is going to lead to unhappiness when j is equal to 0, as it is on the first iteration. That's because you don't have an element with index -1. This is a major problem, even if it isn't the only remaining cause of your crash.
There's a variety of ways to do this, and a variety of issues with the code given.
Here's a working example.
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define LENGTH 20
int main(void)
{
int players = 0;
char switchString[LENGTH];
printf("Hello user, welcome to your basketball team!\n"
"Please enter the number of players on your team.\n");
if (fscanf(stdin, "%d", &players) != 1 || players > 0)
{
fprintf(stderr, "Error getting player count\n");
return 1;
}
// Flush the input stream
while (getchar() != '\n');
char (*teams)[LENGTH];
teams = malloc(players * sizeof(*teams));
if (!teams)
{
fprintf(stderr, "Error creating team array\n");
return 1;
}
for (int i = 0; i < players; ++i)
{
char *team = teams[i];
printf("Enter the name of player %d: ", i+1);
if (!fgets(team, LENGTH, stdin))
{
fprintf(stderr, "Error getting name of player\n");
free(team);
return 1;
}
char *endline = strchr(team, '\n');
if (endline)
*endline = '\0';
}
// Bubble sort
for (int i = 0; i < players; ++i)
{
for (int j = i; j < players; ++j)
{
if (strcmp(teams[j - 1], teams[j]) > 0)
{
strncpy(switchString, teams[j-1], LENGTH);
strncpy(teams[j-1], teams[j], LENGTH);
strncpy(teams[j], switchString, LENGTH);
}
}
}
for (int i = 0; i < players; i++)
{
printf("%s\n", teams[i]);
}
free(teams);
return 0;
Let's go through this solution piece by piece.
if (fscanf(stdin, "%d", &players) != 1 || players > 0)
{
fprintf(stderr, "Error getting player count\n");
return 1;
}
// Flush the input stream
while (getchar() != '\n');
This will get the number of players and make sure that we the newline we gave doesn't mess with the following inputs.
char (*teams)[LENGTH];
teams = malloc(players * sizeof(*teams));
if (!teams)
{
fprintf(stderr, "Error creating team array\n");
return 1;
}
This completely changes how we store teams.
Why do more mallocs than you have to?
This declares teams as a pointer to an array of LENGTH.
This means that when we malloc, we store all of the memory for the names next to each other, and teams[0] points to the char * of the first team, teams[1] points to the char * of the second team, and so on.
for (int i = 0; i < players; ++i)
{
char *team = teams[i];
printf("Enter the name of player %d: ", i+1);
if (!fgets(team, LENGTH, stdin))
{
fprintf(stderr, "Error getting name of player\n");
free(team);
return 1;
}
char *endline = strchr(team, '\n');
if (endline)
*endline = '\0';
}
Instead of using *(team + i) everywhere, the type of teams allows us to naturally refer to each element like an array of arrays.
We also do a check that fgets succeeds.
We also use strchr to remove the newline as it is clearer to read.
// Bubble sort
for (int i = 0; i < players; ++i)
{
for (int j = 0; j < players; ++j)
{
if (strcmp(teams[j - 1], teams[j]) > 0)
{
strncpy(switchString, teams[j-1], LENGTH);
strncpy(teams[j-1], teams[j], LENGTH);
strncpy(teams[j], switchString, LENGTH);
}
}
}
We now use strncpy for safety. Bubble sort can also be made more efficient.
Notice that in the original code, free was only called for the array of pointers (char **), and not each char * pointer.
So I may be attacking this the wrong way; I was learning a bit of Javascript and wrote a program that will find a string contained in another string and store the matches in an array (sorry if that didn't make too much sense, seeing my C program should help). I tried to translate my program to C, but it doesn't work; I think my issue is data types:
int main () {
char text[58];
strcpy(text, "I am James, James the Great, a pretty cool guy named James");
char store[16];
char name[6] = "James";
for (int i = 0; i <= 16; i++) {
if (text[i] == 'J') {
for (int k = i; k < i + 6; k++) {
store[k] = text[i];
}
}
}
int a = sizeof(store) / sizeof(store[0]);
for (int b = 0; b < a; b++) {
/* This should print out the values stored in the store array */
printf("%d", store[b]);
}
return 0;
}
My expected result would be something like:
JamesJamesJames
Instead I get:
10000747474747474-6374747474
So I'm assuming it's doing exactly what I told it to do, just not storing the letters into the array as letters, a bit confusing. Is there a better way to do this?
This is the javascript code I was trying to translate:
var text = "I am James, James the Great, a pretty cool guy named James";
var myName = "James";
var hits =[];
for (i = 0; i < text.length; i++) {
if (text[i] === "J") {
for (var j = i; j < i + myName.length ; j++) {
hits.push(text[j]);
}
}
}
if (hits.length === 0) {
console.log("Your name wasn't found!");
} else{
console.log(hits);
}
You are going to break store[] with this line
for (int k = i; k < i + 6; k++) {
because you are writing to the same index as you found the text in text[]. You also loop one too many times (6)
int ind = 0;
for (int k = 0; k < 5; k++) {
store[ind++] = text[i+k];
}
Then your next statement doesn't tell you anything about the data you collected
int a = sizeof(store) / sizeof(store[0]);
Just remove it, and print ind characters from store[].
You made following mistakes.
for (int i = 0; i <= 16; i++)
You iterate by '16' but this isn't proper length of text.
for (int k = i; k < i + 6; k++)
So you iterate by "i, i+1, i+2, i+3, i+4, i+5, i+6" here is 7 chars, "James" have 6.
store[k] = text[i];
You aren't changing "i" value so text[i] always return 'J'. It's better to use savePoistion variable so do I in the following code.
int a = sizeof(store) / sizeof(store[0]);
for (int b = 0; b < a; b++) {
/* This should print out the values stored in the store array */
printf("%d", store[b]);
}
I have no idea what are you trying to do here. It's really unnecessary.
printf("%d", store[b]);
"%d" means that you are printing integers so don't be surprised that your output was numbers. Just simply printf("%s\n", store);
This should look like this
int main () {
char text[58];
strcpy(text, "I am James, James the Great, a pretty cool guy named James");
char store[20];
int len = strlen(text);
int savePosition = 0;
int i, k;
for (i = 0; i < len; i++) {
if (text[i] == 'J') {
for ( k = i; k < i + 5; k++) {
store[savePosition] = text[k];
++savePosition;
}
}
}
store[savePosition] = '\0';
printf("%s\n", store);
return 0;
}
int main (void) {
char text[] = "I am James, James the Great, a pretty cool guy named James";
char name[] = "James";
char store[16] = {0};
int store_index = 0;
for (int i = 0; i < strlen(text); i++) {
if (text[i] == 'J') {
for (int k = i; k < i + strlen(name); k++) {
store[store_index++] = text[k];
}
}
}
if(strlen(store)==0) {
printf("Your name wasn't found!\n");
} else {
printf("%s\n", store);
}
return 0;
}
rewrite version.
int main (void) {
char text[] = "I am James, James the Great, a pretty cool guy named James";
char name[] = "James";
char store[sizeof(text)];
char *p = strstr(text, name);
if(p == NULL) {
printf("Your name wasn't found!\n");
} else {
int len = strlen(name);
int index = 0;
do {
memcpy(store + index, name, len);
index += len;
p = strstr(p + len, name);
} while(p != NULL);
store[index] = 0;
printf("%s\n", store);
}
return 0;
}