Acquisition of string c - c

This is the code of a simple code of game of anagram:
#define NP 5
#define LP 10
void anagrammi() {
srand(time (NULL));
char words[NP][LP] = {"cane", "gatto", "gallo", "rana", "ibis"};
typedef struct {
char parola[LP];
int usati[LP];
char anagramma[LP];
}an ;
int a, len, i, j, cont;
char merda[LP], c;
an yoda;
a = rand()%5;
strcpy(yoda.parola, words[a]);
len = strlen(yoda.parola);
for (i = 0; i < len; i++){
yoda.usati[i] = len+2;
}
i = 0;
while (i < len){
cont = 0;
a = rand()%len;
for (j = 0; j < len; j++){
if (a == yoda.usati[j]) cont++;
} if (cont == 0) {
yoda.usati[i] = a;
yoda.anagramma[i] = yoda.parola[a];
i++;
}
}
j = 0;
cont = 0;
yoda.anagramma[i] = '\0';
printf("Anagramma di %s ? ", yoda.anagramma);
c = getchar() ;
while( c != '\n' && j < LP ){
merda[j] = c ;
j++ ;
c = getchar(); }
merda[j] = '\0';
for (i = 0; i < len; i++){
if (merda[i] =! yoda.parola[i]) cont++;
printf("\n%d", cont);
printf("\n%c", merda[i]);
printf("\n%c", yoda.parola[i]);
}
if (cont =! 0) printf("\nFALSE");
else printf ("\nTRUE");
}
The program goes, but when I insert the word and compare this to the original word, the final output is always FALSE, even if I put the right word. The problem occurs also without \0.Can anyone give me a hand?
Thanks to the answer, this is the perfectly working programm:
void anagrammi() {
srand(time (NULL));
char words[NP][LP] = {"cane", "gatto", "gallo", "rana", "ibis"};
typedef struct {
char parola[LP];
int usati[LP];
char anagramma[LP];
}an ;
int a, len, i, j, cont;
char merda[LP], c;
an yoda;
a = rand()%5;
strcpy(yoda.parola, words[a]);
len = strlen(yoda.parola);
for (i = 0; i < len; i++){
yoda.usati[i] = len+2;
}
i = 0;
while (i < len){
cont = 0;
a = rand()%len;
for (j = 0; j < len; j++){
if (a == yoda.usati[j]) cont++;
} if (cont == 0) {
yoda.usati[i] = a;
yoda.anagramma[i] = yoda.parola[a];
i++;
}
}
j = 0;
cont = 0;
yoda.anagramma[i] = '\0';
printf("Anagramma di %s ? ", yoda.anagramma);
c = getchar() ;
while( c != '\n' && j < LP ){
merda[j] = c ;
j++ ;
c = getchar(); }
for (i = 0; i < len; i++){
if (merda[i] != yoda.parola[i]) cont++;
}
i = strlen(merda);
if (cont != 0 || i > len ) printf("\nNON HAI INDOVINATO");
else printf ("\nHAI INDOVINATO");
}

(cont =! 0) that should be (cont != 0)
– kaylum

Related

Each function works, but not together

i have string like "1111 1010 101010" and i have two functions
int getFirstNumber(char *a){
char *p = strtok(a," ");
char str[strlen(p)];
for (int i = 0; i < strlen(p); ++i){
str[i] = p[i];
}
return getBin(str);
}
int getThirdNumber(char *a){
char *p = strtok(a," ");
int k = 0;
while (p != NULL){
p = strtok(NULL," ");
if (k == 1){
break;
}
k +=1;
}
char str[strlen(p)-1];
for (int i = 0; i < strlen(p) - 1; ++i){
str[i] = p[i];
}
return getBin(str);
}
getBin
int getBin(char *a){
int k = 1;
int res;
for (int i = strlen(a) - 1; i >= 0;i -=1){
if (a[i] == '1'){
res += k;
}
k *= 2;
}
return res;
}
The problem is if i use getFirstNumber or use getThirdNumber alone, it works, but together i have Segmentation Fault. What is wrong,

C - How to input and insert a string into an array of strings?

I want to insert string to the array until I type "ok". Why I am getting just "ok" and original array at the output?
int main(void)
{
char b[20];
char* str[10] = { "1","2" };
int i = 2;
while (1) {
gets(b);
if (strcmp(b, "ok") == 0) break;
str[i] = b;
i++;
}
for (int j = 0; j < i; j++)
printf("%s ", str[j]);
return 0;
}
You need to allocate a string on each iteration:
int main(void)
{
char* b;
char* str[10] = { "1","2" };
int i = 2;
while (1) {
b = malloc(20);
gets(b);
if (strcmp(b, "ok") == 0) break;
str[i] = b;
i++;
}
for (int j = 0; j < i; j++)
printf("%s ", str[j]);
// free allocated strings
while (i > 2)
free(str[--i]);
return 0;
}
They all point to b, which gets overwritten in each iteration.
You need to create a copy of the string when you assign it:
str[i] = strdup(b);
You also may consider using fgets instead of gets; however, you will need to remove the newline:
size_t size;
fgets(str, 20, stdin);
size = strlen(str);
if(str[size-1] == '\n')
str[size-1] = '\0';
Also, print a newline at the end of your program, so it won't interfere with the shell:
putchar('\n');
Full code:
int main(void)
{
char b[20];
char* str[10] = { "1","2" };
int i = 2;
while (1) {
size_t size;
fgets(str, 20, stdin);
size = strlen(str);
if(str[size-1] == '\n')
str[size-1] = '\0';
if (strcmp(b, "ok") == 0)
break;
str[i] = strdup(b);
i++;
}
for (int j = 0; j < i; j++)
printf("%s ", str[j]);
putchar('\n');
return 0;
}
You need to make a copy of the input string, then save a pointer to the copy of the input string in your array. Something like:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int main(void)
{
char b[20];
char *str[10] = { "1","2" };
int i = 2;
char *p;
size_t lenb;
for(i = 2 ; i < 10 ; ++i)
{
fgets(b, sizeof(b), stdin);
lenb = strlen(b);
if(lenb > 0 && *(b+lenb-1) == '\n')
{
*(b+lenb-1) = '\0'; /* overwrite the trailing \n */
lenb = strlen(b);
}
if (strcmp(b, "ok") == 0)
break;
p = malloc(lenb+1);
strcpy(p, b);
str[i] = p;
}
for (int j = 0; j < i; j++)
printf("%s\n", str[j]);
return 0;
}

Different output in Windows and Linux (gcc) C compilers

I have a program which solves maze, so that it finds possible route from Start(S) to Exit(E).Here is my Maze:
1111S11110
0000010001
110100010d
t001111110
0100000001
0111111101
1111111101
00000D01T1
0111110001
0000E01110
The possible route to it is :
Start S W W S S S E E E E E E S S S S W W N W W W W W W S S E E E E Exit
which is correct and i get it on CodeBlocks, However when i compile my code on dev through putty i get this:
Start S S S S S W N N W S W N N N W N Exit
Here is my whole code:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <ctype.h>
// Global Variables for use
int matrixSize,startX,startY,exitX,exitY;
char src[1500] = " ";
char Ndirection[50] = " N ";
char Sdirection[50] = " S ";
char Edirection[50] = " E ";
char Wdirection[50] = " W ";
// Function for finding the array length
int numOfLines(FILE *const mazeFile) {
int c, count;
count = 0;
for (;; ) {
c = fgetc(mazeFile);
if (c == EOF)
break;
if (c == '\n')
++count; // end of line => increment line counter
}
rewind(mazeFile);
return count+1;
}
int capLetter(char ch){
int result = 0;
if(ch >= 'A' && ch <= 'Z'){
result = 1;
}
return result;
}
int lowLetter(char ch){
int result = 0;
if(ch >= 'a' && ch <= 'z'){
result = 1;
}
return result;
}
int isSafe(char Mazearray[matrixSize][matrixSize],int x,int y){
if(x >= 0 && x < matrixSize && y >= 0 && y < matrixSize && Mazearray[x][y] != '1'){
return 1;
}
return 0;
}
void MazeSolution(char Mazearray[matrixSize][matrixSize],int x,int y,char pathArray[matrixSize][matrixSize],char wasHereArray[matrixSize][matrixSize]){
if(recursiveMaze(Mazearray,x,y,pathArray,wasHereArray) == 0){
printf("There does not exist a possible solution!!!");
}
else{
pathArray[startX][startY] = 'S';
}
}
int recursiveMaze(char Mazearray[matrixSize][matrixSize],int x,int y,char pathArray[matrixSize][matrixSize],char wasHereArray[matrixSize][matrixSize]){
if(x == startX && y == startY){
pathArray[x][y] = 'S';
}
if(x == exitX && y == exitY){
pathArray[x][y] = 'E';
return 1;
}
// check if the coordinate is safe to go(not 1)
if(isSafe(Mazearray,x,y) == 1 && wasHereArray[x][y] != '1'){
wasHereArray[x][y] = '1';
// Move North
if(recursiveMaze(Mazearray,x-1,y,pathArray,wasHereArray) == 1){
pathArray[x][y] = 'R';
strcat(src,Ndirection);
return 1;
}
// Move South
if(recursiveMaze(Mazearray,x+1,y,pathArray,wasHereArray) == 1){
pathArray[x][y] = 'R';
strcat(src,Sdirection);
return 1;
}
// Move East
if(recursiveMaze(Mazearray,x,y+1,pathArray,wasHereArray) == 1){
pathArray[x][y] = 'R';
strcat(src,Edirection);
return 1;
}
// Move West
if(recursiveMaze(Mazearray,x,y-1,pathArray,wasHereArray) == 1){
pathArray[x][y] = 'R';
strcat(src,Wdirection);
return 1;
}
}
return 0;
}
// Main Function
int main( int argc, char **argv )
{
// Opening the Matrix File
FILE *mazeFile;
mazeFile = fopen(argv[1], "r" );
if( mazeFile == NULL )
return 1;
matrixSize = numOfLines( mazeFile );
// Reading text file into 2D array
int i,j;
char mazeArray [matrixSize][matrixSize];
for (i = 0; i<matrixSize; i++) {
for (j = 0; j<matrixSize; j++) {
fscanf(mazeFile, "%c", &mazeArray[i][j]);
}
char eol;
fscanf(mazeFile, "%c", &eol);
}
// Variables
//Creating path array
char pathArray[matrixSize][matrixSize];
for (i = 0; i < matrixSize; i++){
for (j = 0; j < matrixSize; j++){
pathArray[i][j] = '0';
}
}
// CheckPoint array
char wasHereArray[matrixSize][matrixSize];
for (i = 0; i < matrixSize; i++){
for (j = 0; j < matrixSize; j++){
wasHereArray[i][j] = '0';
}
}
// Finding start and exit indexes
for (i = 0; i<matrixSize; i++) {
for (j = 0; j<matrixSize; j++) {
if(mazeArray[i][j] == 'S'){
startX = i;
startY = j;
}
if(mazeArray[i][j] == 'E'){
exitX = i;
exitY = j;
}
}
}
MazeSolution(mazeArray,startX,startY,pathArray,wasHereArray);
char *data = src;
int length=strlen(data);
char bytes[length];
int n=0;
while(n<=length)
{
bytes[n] = data[length-n-1];
n++;
}
FILE *f = fopen("path.txt", "w");
fprintf(f, "Start %s Exit",bytes);
fclose(mazeFile);
fclose(f);
return 0;
}
I don't know what is wrong and where to start?
DOS line endings are CR-LF ("\r\n") and *nix line endings are just LF ("\n"). Change these lines main:
char eol;
fscanf(mazeFile, "%c", &eol);
to:
int c = fgetc(mazefile); // Slurp a '\r' carriage return or '\n' linefeed character.
if ('\r' == c) {
c = fgetc(mazefile); // slurp the '\n' linefeed character.
}

testcase not running in c program

iam new to c program and facing difficulty in debugging programs.In the below code test case 2 is not running.I have found that the error is in reading interger n in the second test case.someone please hep me with this issue.Also please recommend me with some tools that can be ued for debugging c programs using terminal.Thanks for help
#include <stdio.h>
#include <stdlib.h>
int read(){
int r = 0;
char c = getchar_unlocked();
while(c >= '0' && c <= '9'){
r = r*10 + c - 48 ;
c = getchar_unlocked();
}
return r;
}
void main(){
int t = 0;
t = read();
int rr = 0;
for(rr = 0;rr < t;rr++){
int i,n = 0;
n = read();
int *p = (int *)calloc(n,sizeof(int));
for(i = 0;i < n;++i){
*(p+i) = getchar_unlocked() - 48;
}
int no,nz = 0;
for(i = 0;i < n;++i){
if(*(p+i) == 0){nz += 1;}
if(*(p+i) == 1){no += 1;}
}
int k = 0;
if(((no)%2 == 0) && ((nz)%2) == 0){
k = -1;
}
if(((no)%2 == 0) && ((nz)%2) == 1){
k = 0;
}
if(((no)%2 == 1) && ((nz)%2) == 0){
k = 1;
}
if(((no)%2 == 1) && ((nz)%2) == 1){
k = 1;
}
int result = 0;printf("%d\n",5556);
if(k == 1){
for(i = 0;i < n;++i){
if(*(p+i) == 1){
result = i+1 ;
break;
}
}
}
if(k == 0){
for(i = 0;i < n;++i){
if(*(p+i) == 0){
result = i+1 ;
break;
}
}
}
printf("%d\n",result);
}
}
Your strategy to read an integer is flawed. You don't have the logic to skip whitespaces. I would change the function name to read_int and change its implementation to
int read(){
int n;
if ( scanf("%d", &n) != 1 )
{
// Deal with the error
}
return n;
}
Also, change
*(p+i) = getchar_unlocked() - 48;
to
*(p+i) = read_int();
or a more intuitive version:
p[i] = read_int();
With those changes, I am able to read and process the numbers. But I still get the wrong output. I'll let you figure the logic error in your code.
Additional Comments
main is expected to return an int. If your compiler didn't complain about that, it's time to up the warning level. I use -Wall by default.
When you are in the process of debugging your code, it's always good to test the code that reads the input to make sure that there is no error in reading the input.
Here's what I did to your code:
#include <stdio.h>
#include <stdlib.h>
int read_int(){
int n;
if ( scanf("%d", &n) != 1 )
{
// Deal with the error.
}
return n;
}
int main(){
int t = 0;
int rr = 0;
t = read_int();
printf("t = %d\n", t);
for(rr = 0;rr < t;rr++){
int i,n = 0;
n = read_int();
printf("n = %d\n", n);
int *p = (int *)calloc(n,sizeof(int));
for(i = 0;i < n;++i){
p[i] = read_int();
printf("p[%d] = %d\n", i, p[i]);
}
int no,nz = 0;
for(i = 0;i < n;++i){
if(*(p+i) == 0){nz += 1;}
if(*(p+i) == 1){no += 1;}
}
int k = 0;
if(((no)%2 == 0) && ((nz)%2) == 0){
k = -1;
}
if(((no)%2 == 0) && ((nz)%2) == 1){
k = 0;
}
if(((no)%2 == 1) && ((nz)%2) == 0){
k = 1;
}
if(((no)%2 == 1) && ((nz)%2) == 1){
k = 1;
}
int result = 0;
// printf("%d\n",5556);
if(k == 1){
for(i = 0;i < n;++i){
if(*(p+i) == 1){
result = i+1 ;
break;
}
}
}
if(k == 0){
for(i = 0;i < n;++i){
if(*(p+i) == 0){
result = i+1 ;
break;
}
}
}
printf("%d\n",result);
}
return 0;
}

C histogram of words printing problems

I have this code, what i want it to do is print the string that represents the word, and print the number of times it occurred in the file, instead it outprints something liek this: (a load of blank space) and then this number -1076720020, which i have no idea where it came from, how would i go about fixing this?
#include <stdio.h>
#include <string.h>
#include <ctype.h>
#include <stdlib.h>
struct podatki {
char beseda[1000];
int frekvenca;
};
void zamenjaj(char *str1, char *str2) {
char *beseda2 = (char *)malloc((strlen(str1) + 1) * sizeof(char));
strcpy(beseda2, str1);
strcpy(str1, str2);
strcpy(str2, beseda2);
free(beseda2);
}
int posodobi(struct podatki s[], const char unit[], int count) {
int i =0;
for (i = 0; i < count; i++) {
if (strcmp(s[i].beseda, unit) == 0) {
s[i].frekvenca++;
return count;
}
}
strcpy(s[count].beseda, unit);
s[count].frekvenca++;
return (count + 1);
}
int main() {
int stBes;
scanf("%d", &stBes);
//zacetne deklaracije
struct podatki s[1000];
char string[1000], unit[2000], c;
int i = 0;
int frekvenca = 0;
int j = 0;
int count = 0;
int num = 0;
//branje
for (i = 0; i < 1000; i++) {
s[i].frekvenca = 0;
}
i = 0;
do {
fflush(stdin);
c = getchar();
string[i++] = c;
} while (c != '\n');
//pretvori v majhne crke
char *p;
for (p = string; *p != '\0'; ++p) {
*p = tolower(*p);
}
string[i - 1] = '\0';
for (i = 0; i < strlen(string); i++) {
while (i < strlen(string) && string[i] != ' ' && !ispunct(string[i])) {
unit[j++] = string[i++];
}
if (j != 0) {
unit[j] = '\0';
count = posodobi(s, unit, count);
j = 0;
}
}
int a;
for (i = 0; i < count; ++i) {
for (j = i + 1; j < count; ++j) {
if (s[i].frekvenca < s[j].frekvenca) {
a = s[i].frekvenca;
s[i].frekvenca = s[j].frekvenca;
s[j].frekvenca = a;
zamenjaj(s[i].beseda, s[j].beseda);
}
}
}
for (i = 0; i < count; i++) {
for (j = 1; j < count; j++) {
if (s[i].frekvenca == s[j].frekvenca){
if (strcmp(s[i].beseda, s[j].beseda) < 0) {
a = s[i].frekvenca;
s[i].frekvenca = s[j].frekvenca;
s[j].frekvenca = a;
zamenjaj(s[i].beseda, s[j].beseda);
}
}
}
}
//printanje
for (i = 0; i < stBes; i++) {
printf("%s\t %d\n", s[i].beseda, s[i].beseda);
if (s[i].frekvenca > 1) {
num++;
}
}
return 0;
}
The problem is that you convert the string to lower case before nul terminating it.
Here
i = 0;
do {
fflush(stdin);
c = getchar();
string[i++] = c;
} while (c != '\n');
/* Goes here <---------------------+ */
/* | */
//pretvori v majhne crke | */
char *p; /* | */
for (p = string; *p != '\0'; ++p) {/* | */
*p = tolower(*p);/* | */
} /* | */
/* | */
string[i - 1] = '\0'; /* ---------------------+ */
You should also remove the fflush(stdin) and instead use getchar() to fetch the white space characters ignored by the previous scanf(), and please use scanf() correctly and check it's returned value.

Resources