Stray characters in char array - c

I am having a problem with this code, this code is a encryption for a rail cipher and if you enter in an input "testing" you should get an output "tietnsg" which i do get.
However if i change the input to "testingj" i get an output of "tietnjsgp?²!lj" i can see from my debugging the "?²!lj" appears to be tagged on during the last fill in the toCipher function
does anyone know how to fix it other than the way that i did it?
/*
CIS Computer Secutrity Program 1
10-10-14
*/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <malloc.h>
char *toCipher(char **arr,int x,int y);
char *Encrypt(char *pT, int size);
char **create(int x,int y);
void FreeArr(char **array, int y);
void print(char *word,int strl);
int main(){
char pt[]= "testingj";
char *word = Encrypt(pt,3);
print(word, sizeof(pt));
free(word);
}
/*
Take in a pointer to a word, and the lenght of the string
Post print each char in the array, (used beacuase i had some issues with the memory, i keep getting extra adresses
*/
void print(char *word,int strl){
int i;
for(i=0;i<strl-1;i++){
printf("this is correct %c",word[i]);
}
printf("\n");
}
/*
Pre, take in the pointer to the plain text word to be encrypted as well as the depth of the Encryption desired
Post: Construct the array, insert values into the 2d array, convert the 2d array to a 1d array and return the 1d array
*/
char *Encrypt(char *word,int y){
int x = strlen(word);
int counter=0;
int ycomp=0;
int rate=1;
char **rail = create(x,y);
while(counter<x){
if(ycomp==y-1){
rate=-1;
}
if(ycomp==0){
rate=1;
}
rail[counter][ycomp]=word[counter];
ycomp=ycomp+rate;
counter++;
}//end of rail construction
char *DrWord = toCipher(rail,x,y);
FreeArr(rail,y);
return(DrWord);
}
/*
Create a dynamic 2d array of chars for the rail cypher to use
Take in the dimensions
return the pointer of the rails initial address, after it created the space for the rail
*/
char *toCipher(char **arr,int x,int y){
int xI =0;
int yI=0;
int counter =0;
char *word = (char*)malloc(x);
int i;
for(yI=0;yI<y;yI++){
for(xI=0;xI<x;xI++){
if(arr[xI][yI]!= 0){
word[counter]=arr[xI][yI];
counter++;
}
}
}
printf("this is the problem %s\n",word);
return(word);
}
char **create(int x, int y){
char **rail;
int i,j;
rail = malloc(sizeof(char**)*x);
for(i=0;i<x;i++){
rail[i]= (char*)malloc(y * sizeof(char*));
}
for(i=0;i<y;i++){
for(j=0;j<x;j++){
rail[j][i]= 0;
}
}
return(rail);
}
/*
Pre, take in a malloc'd array, with the height of the array
free the malloc calls one by one, and finally free the initial adress
*/
void FreeArr(char **array, int y){
int i;
for(i=0;i<y;i++){
free(array[i]);
}
free(array);
}

In toCipher, the word is printed without nul-termination. Either:
char *word = (char*)malloc(x+1); // allocate an extra char for nul.
word[x] = 0; // add the nul at the end.
or:
printf("this is the problem %.*s\n",x,word); // limit characters printed to x.

I forgot to initialize word to 0, the tagged memory if you watch it in debug mode was not being replaced, therefore was tagged along in the newly constructed string

Related

Allocating dinamicaly memory problems and VLA with characters

I know I should not use c and c++ at the same time.
Can someone say why the above code are working using new?
the purpose is to remove the central character of an word given by keyboard ex: "abcde" to "abde"
I was asking if the creation of VLA is correct or not... apparently it returns what I want BUT the same main code without the other functions crashes.
I searched throw internet and i discovered that i should initialize the size ('n' in my case)of the VLA's.
Code using functions and new:
#include <stdio.h>
#include <string.h>
int citirea_sirului(char *s1, char *s2)
{
int d;
printf("Cuvantul: ");
gets(s1);
d=strlen(s1);
for(int i=0;i<d;i+=1)
{
*(s2+i)=*(s1+i);
}
return d;
}
void prelucrarea_afis_siruluiC(char *b, int d, char *a){
strcpy(a,b+(d/2)+1);
strcpy(b+(d/2),"");
strcat(b,a);
puts(b);
}
int main(){
int n;
char *cuv,*ccuv;
cuv=new char[n];
ccuv=new char[n];
n=citirea_sirului(cuv,ccuv);
printf("Dimensiunea Cuvantului: %d\n",n);
printf("\nSir prelucrat: \n");
prelucrarea_afis_siruluiC(ccuv,n,cuv);
delete[] ccuv;
delete[] cuv;
return 0;
}
Code without functions:
#include <stdio.h>
#include <string.h>
int main(){
int n;
char cuv[n], ccuv[n];
printf("Cuvantul: ");
gets(cuv);
n=strlen(cuv);
printf("Dimensiunea Cuvantului: %d",n);
for(int i=0;i<n;i++)
{
ccuv[i]=cuv[i];
}
strcpy(cuv,cuv+(n/2)+1);
strcpy(ccuv+(n/2),"");
strcat(ccuv,cuv);
printf("\nCuvantul prelucrat: %s",ccuv);
return 0;
}

Why can't I separate letters in a string?

I want to take all the letters in a string and put it in a array separately. But I am receiving some error and I could not figure out.
10 20 E:\FALL SEM 20-21\CS\C codes\Untitled3.c [Warning] passing argument 2 of 'strcpy' makes pointer from integer without a cast
My code is
#include<stdio.h>
#include<string.h>
char array[10][100],string[100];
int top=0;
void push(char elem)
{
strcpy(array[top],elem);
top++;
}
int main()
{
printf("Enter the string: \n");
fgets(string,100,stdin);
int length;
length=strlen(string);
int i=0;
while((string[i])!='\0')
{
push(string[i]);
i++;
}
printf("%d",length);
}
strcpy() is for copying strings (sequences of characters terminated by a null-character). To use that, you should make strings from the characters and pass them. Also you have to fix the type of the argument of push().
#include<stdio.h>
#include<string.h>
char array[10][100],string[100];
int top=0;
void push(const char* elem) /* use const char* to receive strings that won't be modified */
{
strcpy(array[top],elem);
top++;
}
int main(void)
{
printf("Enter the string: \n");
fgets(string,100,stdin);
int length;
length=strlen(string);
int i=0;
while((string[i])!='\0')
{
char str[2] = {string[i], '\0'}; /* create a string */
push(str); /* and push that */
i++;
}
printf("%d",length);
}

C array of struct issues

#include <stdlib.h>
#include <stdio.h>
#include <string.h>
struct individual {
char name[32];
int stats[7];
char role;
};
void create_array(struct individual **array){
*array = malloc(sizeof(struct individual)); //allocate initial memory space
}
void resize_array(struct individual **array, unsigned char num) {
printf("%d\n", *array);
*array = realloc(*array, num * sizeof(struct individual));
printf("%d\n", *array);
printf("resize success\n");
}
void problem(struct individual **f_array, unsigned char *f_num) {
*f_num = 2;
printf("%d\n", *f_array);
resize_array(f_array, *f_num);
printf("%d\n", *f_array);
strcpy(f_array[*f_num - 1]->name, "test value"); //CRASH LINE
}
int main() {
unsigned char f_num = 0;
struct individual *f_array;
create_array(&f_array);
problem(&f_array, &f_num);
}
This code crashes on the line marked "CRASH LINE". While it is not shown here, doing this same code setting (*f_num = 1) does not result in an error. While passing *f_array as itself (with appropriate alterations to the code in problem) does not result in an error, the values given after problem is exited result in nonsense being given, as the pointer reverts to it's pre-resize state. Any help appreciated.
The problem is the line accessing that value.
The line should read like this:
strcpy((*f_array)[*f_num - 1].name, "test value"); // doesn't crash any more :)
To break it down a little bit:
f_array is a pointer to the array of structs, need to dereference it before indexing
[*f_num - 1] accesses element 1 of the array.

C program char pointer not displaying character after passing through functions

I would love your help in solving this as I have not found a solution in the many examples and videos I found.
I am to create a scrabble game using C programming but for some reason when I pass the character pointer through my functions, the last one to display the scrabble board does not print the letter from my previous function.
Instead of printing the randomly generated character, it prints an empty string.
I have copied the parts of the code that is involved.
#include<stdio.h>
#include<stdlib.h>
#include <string.h>
int k,j;
char * grid[8][8];
void play(int x, int y, char*c){
grid[x-1][y-1] = c;
}
void display(){
for (j=0; j<8; j++){
for (k=0; k<8; k++){
if (strcmp(grid[k][j], "")==0){
printf("%s", grid[k][j]);
}else{
printf("%s ", grid[k][j]);
}
}
}
}
void start(){
char c[2], *rc;
c[0] = rand();
rc = &c[0];
play(rand()%8, rand()%8, rc);
}
int main(int argc, char *argv[]){
play(3,7,"a");
play(4,5,"b");
start();
display();
}
Some comment :
void start(){
char c[2], *rc; // c string is local to the function
c[0] = rand();
rc = &c[0]; // rc points to a string inside the function
play(rand()%8, rand()%8, rc); // you save an address local to the function
}
When start function exits, rc value (= c address) are no more meaningful.
You should allocate memory in the function to have valid and addresses.

Unable to sort a list of strings alphabetically in C

I wrote a program to accept 5 strings from user and then display them sorted alphabetically using bubble-sort algorithm. But, the strings are being displayed in the same order as they were entered. Please tell me what am I doing wrong here.
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
void sSwap(char *s1, char *s2);
int main(){
char *sList[5],input[100],*p;
int i,j;
puts("Enter 5 strings");
for(i=0;i<5;i++){
gets(input);
sList[i] = (char *)malloc(strlen(input)+1);
strcpy(sList[i],input);
}
puts("");
for(i=3;i>=0;i--){
for(j=0;j<=i;j++){
if(strcmp(sList[j],sList[j+1])>0)
sSwap(sList[j],sList[j+1]);
}
}
for(i=0;i<5;i++)
puts(sList[i]);
return 0;
}
void sSwap(char *s1, char *s2){
char *temp;
temp = s1;
s1 = s2;
s2 = temp;
}
as you were told, your swap function getting values and swap them by value, meaning that when you leave the function the changes will not be saved and old values will return. try this
void sSwap(char **s1, char **s2);
int main(){
char *sList[5],input[100],*p;
int i,j;
puts("Enter 5 strings");
for(i=0;i<5;i++){
gets(input);
sList[i] = (char *)malloc(strlen(input)+1);
strcpy(sList[i],input);
}
puts("");
for(i=3;i>=0;i--){
for(j=0;j<=i;j++){
if(strcmp(sList[j],sList[j+1])>0)
sSwap(&sList[j],&sList[j+1]);
}
}
for(i=0;i<5;i++)
puts(sList[i]);
return 0;
}
void sSwap(char **s1, char **s2){
char *temp;
temp = *s1;
*s1 = *s2;
*s2 = temp;
}
One of your problem is that when you swap two strings, you doesn't check if you have to swap it with the new neighboors of this string.
So I would do a recursive function to solve this. Like if you swap, you call the function (let's say void sort(char **list, int index)) :
sort(sList, 0) //to start from beginning and check the new order
If the strings are equals or in the right order, like :
sort(sList, currentListIndex);
So you would have :
void sort(char **sList, int index) {
if (sList[index+1]) {
if (strcmp(sList[index],sList[index+1]) > 0){
sSwap(sList, index); // you can swap direclty on the tab
return sort(sList, 0);
}
return sort(sList, index+1);
}
return void;
}
sort(sList, 0);
It's been a while i didn't do C so maybe pointers are wrong, but it's the idea
The qsort function is in the stdlib.h
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
you define the number of elements in array
#define n_array sizeof(array)/sizeof(const char *)
and the comparison function
static int compare (const void * a, const void * b)
{
return strcmp (*(const char **) a, *(const char **) b);
}
and then in main you should use, replacing sSwap
qsort (array, n_array, sizeof (const char *), compare);

Resources