I was wondering how I would access or change parts of a string through an array of pointers. This is for a program that plays backgammon. That array of pointers points to over 24 different arrays. here is a sample of the code. I want to be able to know how many of each character there is in each 'r#' string. I need to be able to update each string as players move across the board.
char r1[] = {'R','R','|','|','|','\0'};
char r2[] = {'|','|','|','|','|','\0'};
char r3[] = {'|','|','|','|','|','\0'};
char *a[24] = {r1, r2, r3, r4, ... , r24};
minimal reproducible example
#include <stdlib.h>
#include <string.h>
#include <stdio.h>
int main() {
char r1[] = {"RR|||"};
char r2[] = {"|||||"};
char r3[] = {"WWWWW"};
char r4[] = {"|||||"};
char r5[] = {"WWW||"};
const char * a[5] = { r1, r2, r3, r4, r5 };
int to;
for(int i=0; i<10; i++){
printf("enter number here: ");
scanf("%d", &to);
char *to_check = strchr(a[to-1], '|');
if(to_check){
printf("successful \n");
}else{
printf("unsuccessful \n");
}
}
return 0;
}
Related
This is my code:
#include <stdio.h>
#include <string.h>
#define VERSION "2.16.0.0"
int main ()
{
//char buf[] ="2.16.0.0";
int i = 0;
int j ;
char letter[8];
//char a[] = VERSION;
for(i=0;i<8;i++)
{
letter[i] = VERSION[i];
}
char *array;
char* copy = letter ;
while ((array = strtok_r(copy, ".", ©)))
printf("%s\n", array);
printf("%s", array);
}
I split the macro to 2 16 0 0.
Now, I want to format it to 02 16 00 00. How do I do it?
I tried using sprintf() function to format the array but that didn't work out, any other way?
Your program can be simplified in several ways (see below) and I have to point out at least one significant error since the copy of the string in letter does not include the terminating 0.
About how to print, as I understand you would like to print the numerical entries with 2 digits. One method to do that is to convert them to integers and format the output using the printf formatting options:
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#define VERSION "2.16.0.0"
int main ()
{
char *element;
char copy[] = VERSION;
element = strtok(copy, ".");
while (element != NULL)
{
printf("%02d ", atoi(element));
element = strtok(NULL, ".");
}
}
I am trying to use memcpy C library function to swap rows of 2D array(array of strings). Source files for this task is below:
main.c
#include <stdlib.h>
#include "main.h"
char *table[NBLOCK] = {
"abcdefghi",
"defghiabc",
"ghiabcdef",
"bcaefdhig",
"efdhigbca",
"higbcaefd",
"cabfdeigh",
"fdeighcab",
"ighcabfde",
};
int main() {
swap_rows(table, 0, 2);
return 0;
}
main.h
#define NBLOCK 9
#define BLOCK_CELLS 9
void swap_rows(char**, int, int);
shuffle.c
#include <string.h>
#include "main.h"
void swap_rows(char **table, int r1, int r2) {
char tmp[BLOCK_CELLS];
size_t size = sizeof(char) * BLOCK_CELLS;
memcpy(tmp, table[r1], size);
memcpy(table[r1], table[r2], size); /* SIGSEGV here */
memcpy(table[r2], tmp, size);
}
Segmentation fault occurs inside swap_rows function. Out of three memcpy calls shown above, the first one works as expected. I commented out the last two memcpy calls and added below line:
table[0][0] = 'z';
But, segmentation fault occurred again. Why I am not allowed to override values of table in swap_rows function?
You are not allowed to modify string literals.
For more information, see c - Why do I get a segmentation fault when writing to a "char *s" initialized with a string literal, but not "char s[]"?.
You can modify values of pointers to swap rows.
void swap_rows(char **table, int r1, int r2) {
char* tmp;
tmp = table[r1];
table[r1] = table[r2];
table[r2] = tmp;
}
If you prefer to use memcpy():
void swap_rows(char **table, int r1, int r2) {
char* tmp;
size_t size = sizeof(tmp);
memcpy(&tmp, &table[r1], size);
memcpy(&table[r1], &table[r2], size);
memcpy(&table[r2], &tmp, size);
}
In your code table is not defined as a 2D array of char, it is an array of pointers to char initialized with pointers to string literals, which must not be modified.
You get a segmentation fault because the string literals are stored in read-only memory protected by the operating system.
You should either swap the pointers in swap_rows or define table as a real 2D array and swap the rows with an appropriate prototype:
#include <stdlib.h>
//#include "main.h"
#define NBLOCK 9
#define BLOCK_CELLS 9
void swap_rows(char table[][BLOCK_CELLS], int, int);
char table[NBLOCK][BLOCK_CELLS] = {
"abcdefghi",
"defghiabc",
"ghiabcdef",
"bcaefdhig",
"efdhigbca",
"higbcaefd",
"cabfdeigh",
"fdeighcab",
"ighcabfde",
};
int main() {
swap_rows(table, 0, 2);
return 0;
}
void swap_rows(char table[][BLOCK_CELLS], int r1, int r2) {
char tmp[BLOCK_CELLS];
size_t size = sizeof(tmp);
memcpy(tmp, table[r1], size);
memcpy(table[r1], table[r2], size);
memcpy(table[r2], tmp, size);
}
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "stats.h"
/* Size of the Data Set */
#define SIZE (40)
void print_array (unsigned char *p, int l) {
int i;
for (i=0;i<l;i++) {
printf("%d\t",*p);
p++;
}
}
void print_array_int (int *p, int l) {
int i;
for (i=0;i<l;i++) {
printf("%d\t",*p);
p++;
}
}
void typecasting(unsigned char test[SIZE], int array[SIZE]) {
int i=0;
unsigned char *token = strtok(test,",");
while (token) {
if(i<SIZE) {
array[i++] = atoi(token);
}
token = strtok(NULL,",");
}
}
void main() {
int array[SIZE] = {};
unsigned char test[SIZE] = {34,201,190,154,8,194,2,6,114,88,45,76,123,87,25,23,200,122,150,90,92,87,177,244,201,6,12,60,8,2,5,67,7,87,250,230,99,3,100,90};
/* Other Variable Declarations Go Here */
/* Statistics and Printing Functions Go Here */
print_array(test, SIZE);
typecasting(test,array);
print_array_int(array,SIZE);
}
What I want in this code is to convert the array of char into an array of int.
Previously I tried doing this by using pointers but didn't work and it showed stack smashing error. I want to convert this array of char into array of int to perform some mathematical operations.
You are trying too hard. Here's how typecasting should look
void typecasting(unsigned char test[SIZE], int array[SIZE]) {
for (int i = 0; i < SIZE; ++i)
array[i] = test[i];
}
Your code might be suitable if you were converting from a C string, i.e. if your original test array was
char test[] = "34,201,190,154,8,194,2,6,114,88,45,76,123,87,25,23,...";
So I guess you could say you're misunderstanding the nature of char (and unsigned char) in C++. They can represent character data as in char greeting[] = "hello"; or they can represent small integers as in char test[] = {1,2,3};.
I'm writing a C program with inline assembly function that compares two strings if they are same.
When I compile it with 'arm-none-linux-gneabi-gcc' and 'arm-linux-gnueabi-gcc', the results are different. The difference seems to come from keyword 'none' which is place for [vendor] according to google search.
My questions are
Is this the cause of the difference in the results?
If so, what is set as [vendor] in 'arm-linux-gnueabi-gcc'?
My code :
#include <stdio.h>
int * intoneplus(int * i);
char * charoneplus(char * c);
int my_strcmp(const char *src1, const char *src2);
int main(void)
{
const char *a = "Hello world!";
const char *a1 = "Hello world!";
const char *a2 = "hello aorld!";
if(my_strcmp(a, a1)==0)
printf("a and a1 are same sentence\n");
else
printf("a and a1 are different\n");
if(my_strcmp(a, a2)==0)
printf("a and a2 are same sentence\n");
else
printf("a and a2 are different\n");
return 0;
}
int my_strcmp(const char *src1, const char *src2)
{
int ch1, ch2, ret=0;
__asm__ (
"loop:\n\t"
"LDRB %[ch1], [%[src1]], #1 \n\t LDRB %[ch2], [%[src2]], #1\n\t"
"CMP %[ch1], %[ch2]\n\t"
"MOVNE %[ret], #1\n\t BNE done \n\t"
"CMP %[ch1], #0\n\t BNE loop\n\t"
"done:\n\t"
:[ret]"=r"(ret)
:[src1]"r"(src1),[src2]"r"(src2),[ch1]"r"(ch1),[ch2]"r"(ch2)
);
return ret;
}
Compilation and execution results :
#ubuntu:~/test$ arm-linux-gnueabi-gcc -o practice2.out practice2.c -static
#ubuntu:~/test$ qemu-arm practice2.out
464281
a and a1 are different
1
a and a2 are different
#ubuntu:~/test$ arm-none-linux-gnueabi-gcc -o practice2.out practice2.c -static
#ubuntu:~/test$ qemu-arm practice2.out
0
a and a1 are same sentence
1
a and a2 are different
I have a working insertion sort algorithm that sorts integers stored in an array. In a different program I have created a struct with words and a count. I need to sort structs stored in an array alphabetically using the same insertion sort. I understand how to compare them, however I cannot find a way to swap them. Ideas?
typedef struct { char * word; int count; } wordType;
You can swap structs the same way that you swap integers:
wordType tmp;
wordType a = {.word="hello", .count=5};
wordType b = {.word="world", .count=11};
tmp = a;
a = b;
b = tmp;
Demo on ideone.
How to swap them? Just use a temporary structure:
void swapEm (wordType *w1, wordType *w2) {
wordType wx;
memcpy (&wx, w1, sizeof(wx));
memcpy (w1, w2, sizeof(wx));
memcpy (w2, &wx, sizeof(wx));
}
See the following complete program for an example:
#include <stdio.h>
#include <string.h>
typedef struct { char * word; int count; } wordType;
void swapEm (wordType *w1, wordType *w2) {
wordType wx;
memcpy (&wx, w1, sizeof(wx));
memcpy (w1, w2, sizeof(wx));
memcpy (w2, &wx, sizeof(wx));
}
void printOne (char *s, wordType *w) {
printf ("%s: %d [%s]\n", s, w->count, w->word);
}
int main(void) {
wordType w1, w2;
w1.word = strdup ("from Pax."); w1.count = 314159;
w2.word = strdup ("Hello"); w2.count = 271828;
printOne ("w1", &w1); printOne ("w2", &w2);
swapEm (&w1, &w2);
puts ("===");
printOne ("w1", &w1); printOne ("w2", &w2);
free (w1.word); free (w2.word);
return 0;
}
The output of that is:
w1: 314159 [from Pax.]
w2: 271828 [Hello]
===
w1: 271828 [Hello]
w2: 314159 [from Pax.]