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,
Related
I have a array of strings and I want to find the first pseudopalindrome in the array for every string (if there is any). So I decided to sort my array at first, then reverse the word and do a binary search for a reversed word. So here it is what I have so far:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
char len(char *x){
char len = 0;
while (*x != '\0'){
x++;
len++;
}
return len;
}
char compare(char *x, char *y){
char x0 = &x;
char y0 = &y;
while (*x != '\0'){
if (tolower(*x) < tolower(*y)) return -1;
if (tolower(*x) > tolower(*y)) return 1;
x++;
y++;
}
// if we are here it means that strings are equal (case insensitive)
x = &x0;
y = &y0;
while (*x != '\0'){
if (*x > *y) return -1;
if (*x < *y) return 1;
x++;
y++;
}
// strings are equal (case sensitive)
return 0;
}
char *reverse(char *x){
int i, j;
char temp, *rev = NULL;
rev = malloc(sizeof(char)*(len(x)+1));
rev = strcpy(rev,x);
i = 0;
j = len(x) - 1;
while (i < j){
temp = rev[i];
rev[i] = x[j];
rev[j] = temp;
i++;
j--;
}
return rev;
}
int binsearch(char *x, char *A, int len){
int l, r, m, index;
l = 0;
r = len - 1;
index = -1;
while (l <= r){
m = (l + r) / 2;
if (compare(x, A[m]) == 0){
index = m;
r = m - 1;
}
else if (compare(x, A[m]) == -1) r = m - 1;
else l = m + 1;
}
return index;
}
int main()
{
int n, i, j, k, fnd;
char T[10000][101], temp[101];
scanf("%d", &n);
for (i = 0; i < n; i++){
scanf("%s", &T[i]);
}
for (i = 1; i < n; i++){
strcpy(temp, T[i]);
j = i - 1;
while (j >= 0 && compare(T[j], temp) == 1){
strcpy(T[j+1], T[j]);
j--;
}
strcpy(T[j+1], temp);
}
for (i = 0; i < n; i++){
fnd = binsearch(reverse(T[i]), T, n);
printf("%d", fnd);
}
return 0;
}
This program stops executing. The problem is probably with binary search as every function before executes well. But what's wrong with this binary search? Or what else can break the code?
Does the return type causing the problem .. for binary search no return type is mentioned
Edit 1. But you have not mentioned return type for function in its declaration
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <ctype.h>
char len(char *x){
char len = 0;
while (*x != '\0'){
x++;
len++;
}
return len;
}
char compare(char *x, char *y){
char* x0 = x;
char* y0 = y;
while (*x != '\0'){
int a0 = tolower(*x);
int b0 = tolower(*y);
if ( a0 < b0)
return -1;
if ( a0 > b0)
return 1;
x++;
y++;
}
// if we are here it means that strings are equal (case insensitive)
x = x0;
y = y0;
while (*x != '\0'){
if (*x > *y) return -1;
if (*x < *y) return 1;
x++;
y++;
}
// strings are equal (case sensitive)
return 0;
}
char *reverse(char *x){
int i, j;
char temp, *rev = NULL;
rev = malloc(sizeof(char)*(len(x)+1));
rev = strcpy(rev,x);
i = 0;
j = len(x) - 1;
while (i < j){
temp = rev[i];
rev[i] = x[j];
rev[j] = temp;
i++;
j--;
}
return rev;
}
int binarysearch(char *x,char A[][101], int len){
int l, r, m, index;
l = 0;
r = len - 1;
index = -1;
while (l <= r){
m = (l + r) / 2;
if (compare(x, A[m]) == 0){
index = m;
r = m - 1;
}
else if (compare(x, A[m]) == -1) r = m - 1;
else l = m + 1;
}
return index;
}
int main()
{
int n, i, j, k, fnd;
char T[10000][101], temp[101];
scanf("%d", &n);
for (i = 0; i < n; i++){
scanf("%s", &T[i]);
}
for (i = 1; i < n; i++){
strcpy(temp, T[i]);
j = i - 1;
while (j >= 0 && compare(T[j], temp) == 1){
strcpy(T[j+1], T[j]);
j--;
}
strcpy(T[j+1], temp);
}
for (i = 0; i < n; i++){
fnd = binarysearch(reverse(T[i]), T, n);
printf("%d", fnd);
}
return 0;
}
Not really an answer, but code in comments is painful to read.
You may also try to simplify your code; it's quite astonishing to have some much code for just a palindrome; some functions you are reimplementing are part of standard c (strlen, strcasecmp, strdup)
The function for telling if a word is palindrome is expected to really simple; here a sample of what it could be
#include <ctype.h>
#include <stdbool.h>
#include <stdio.h>
#include <string.h>
bool isspeudopalindrom(const char *x){
for (int i = 0; i < strlen(x) / 2; ++i) {
if (tolower(x[i]) != tolower(x[strlen(x) - 1 - i]))
return false;
}
return true;
}
int main(int argc, char *argv[])
{
for (int i = 1; i < argc; i++){
if (isspeudopalindrom(argv[i]))
printf("palindrom\n");
else
printf("not palindrom\n");
}
return 0;
}
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
I'm new in c programming and i'm trying to make a palindrome game. I've given the code below but there is some mistake I'm making and doesn't run can you please give me a hand. Thank you.
The point of the game is to give number to an array, then change with the keys a,d,x,w and try to make it palindrome.
If there is any error can u please give me some advice ?
This is pal.c
#include <stdio.h>
#include "visible.h"
//--------------------------------------------------
// is_pal
//--------------------------------------------------
void print_status(int a[], int* p, int num_mov);
int is_pal(int a[])
{
int b[6];
int i, j;
j = 0;
for (i = 5; i >= 0; i--)
{
b[j] = a[i];
j++;
}
for (i = 0; i <= 5; i++)
{
if (a[i] != b[i]) {
return 0;
}
}
return 1;
}
//--------------------------------------------------
// process_movement
//--------------------------------------------------
void process_movement(int a[], int* p, int num_mov, char c)
{
char d;
d=c;
if(d == 'd')
{
p = a+1;
num_mov++;
print_status(a,p,num_mov);
}
else if(d == 'a')
{
p = a-1;
num_mov++;
print_status(a,p,num_mov);
}
else if(d == 'x')
{
p = malloc(6*sizeof(int));
a = p-1;
num_mov++;
}
else if(d == 'w')
{
p = malloc(6*sizeof(int));
a = p+1;
num_mov++;
}
}
//--------------------------------------------------
// print_status
//--------------------------------------------------
void print_status(int a[], int* p, int num_mov)
{
printf("Number = ");
int i;
for( i = 0; i < 6; i++)
{
printf("%d ", a[i]);
}
printf("\n Number moves = ");
printf("%d", num_mov);
//printf("\n ","%s%", "Pointer is at position ");
printf("%d", *p);
printf("\n");
}
void user_game_palindrome(int pal_num)
{
int a[5];
int i,num_mov;
num_mov = 0;
i = 5;
while (pal_num != 0) {
a[i] = pal_num % 10;
pal_num = pal_num / 10;
i--;
}
int *p = a;
while (is_pal(a) == 1)
{
char c;
print_status(a,p,num_mov);
c = ask_for_command();
process_movement(a,p,num_mov,c);
}
}
This is ex1.c
#include "pal.h"
int main() {
int pal_num = 123342;
user_game_palindrome(pal_num);
return 0;
}
visible.c
#include "visible.h"
#include "conio.h"
//--------------------------------------------------
// gen_num
//--------------------------------------------------
int gen_num(int lb, int ub) {
int num = (rand() % (ub - lb)) + lb;
return num;
}
/* Note: Do not forget to include the following instruction at the beginning of your main() method:
srand(time(NULL));
*/
//--------------------------------------------------
// my_getchar
//--------------------------------------------------
char my_get_char() {
char my_char;
int b = 0;
char dummy_char;
my_char = getchar();
while (b == 0) {
dummy_char = getchar();
if (dummy_char == '\n')
b = 1;
}
return my_char;
}
this is the visible.c ( my teacher told me to include it)
Your conversion from int to array is wrong
for (i = 0; i < 4; i++) {
a[i] = pal_num%10;
pal_num = pal_num % 10;
}
Here, why would this loop end when i is 4. It should go till pal_num is 0. And pal_num = pal_num % 10; should be pal_num = pal_num / 10;
Try something like
i = 0;
while (pal_num != 0) {
a[i] = pal_num % 10;
pal_num = pal_num / 10;
i++;
}
NOTE: Be aware, that this would essentially reverse your int and store in the array.
There's a lot going wrong in your code and you still haven't fixed many things which have been pointed out by others.
as to remove the unnecessary creating of the array b, is_pal can be defined as:
int is_pal(int a[])
{
int i;
for (i = 0; i < 3; ++i)
{
if (a[5-i] != a[i])
return 0;
}
return 1;
}
process_movement doesn't have a case where d == 'w'
user_game_palindrome should have the while loop checking (is_pal(a) == 0)
And you should apply the changes that were suggested by #Haris
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.
I was trying to write my own strtok function.
char * toke(char * out, char * in, char * destr) {
int place = 0;
for(int i = 0; in[i] != '\0'; i++){
for(int d = 0; destr[d] != '\0'; d++){
if(in[i] == destr[d]){
printf("\nMatch.");
place = i;
i = 0;
while(i < place){
out[i] = in[i];
i++;
}
out[place + 1] = '\0';
i = place;
}
}
}
return out;
}
Program:
int main(){
char * pr;
char * o;
char * in = "Hello-World";
pr = toke(o, in, "-");
printf(pr);
return 0;
}
It keeps on seg-faulting and I can't figure out why.
Your 'out' pointer is not initialized and this:
out[i] = in[i];
throws the exception