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;
}
Related
I have the following function, which, given a string, should find the most recurrent couple of letters in it and store the result in a different string.
For example - for the string "ababa", the most recurrent couple would be "ba", and for "excxexd" it would be "ex". This is the code:
#include <stdio.h>
#include <stdlib.h>
#include <stdbool.h>
#include <string.h>
void printError(){
printf("Error: please check your input\n");
}
bool isLexicographicallyPreceding(char couple1[], char couple2[])
{
if (strcmp(couple1, couple2)>=0) return true;
return false;
}
void coupleDetector(int length, char word[], char result[])
{
char couples[length-1][2];
for (int i=0; i<length-1; i++)
{
char couple[2] = {word[i], word[i+1]};
strcpy(couples[i], couple);
}
char element[]="";
int count=0;
for (int j=0; j<length-1; j++)
{
char tempElement[2];
strcpy(tempElement,couples[j]);
int tempCount=0;
for (int p=0; p<length-1; p++)
{
if (couples[p]==tempElement) tempCount++;
}
if (tempCount>count)
{
strcpy(element, tempElement);
count=tempCount;
}
if (tempCount==count)
{
if (isLexicographicallyPreceding(tempElement,element) == true) strcpy(element, tempElement);
}
}
strcpy(result,element);
}
int main() {
//Supposed to print "ba" but instead presents "stack smashing detected".
int length=5;
char arr[] = "ababa";
char mostCommonCouple[2];
coupleDetector(length,arr,mostCommonCouple);
printf("%s", mostCommonCouple);
return 0;
}
The code compiles without errors, but for some reason does not work as intended but prints out "stack smashing detected". Why would that be? Advices would be very helpful.
Thanks.
In trying out your program, I found a few of your character arrays undersized. Character arrays (strings) need to be sized large enough to also include the null terminator value in the array. So in many locations, having a two-character array size is not sufficient and was the cause of the stack smashing. With that in mind, following is a refactored version of your program.
#include <stdio.h>
#include <stdlib.h>
#include <stdbool.h>
#include <string.h>
void printError()
{
printf("Error: please check your input\n");
}
bool isLexicographicallyPreceding(char couple1[], char couple2[])
{
if (strcmp(couple1, couple2)>=0) return true;
return false;
}
void coupleDetector(int length, char word[], char result[])
{
char couples[length-1][3];
for (int i=0; i<length-1; i++)
{
char couple[3] = {word[i], word[i+1], '\0'};
strcpy(couples[i], couple);
}
char element[3]; /* Define the character array */
strcpy(element, ""); /* Then initialize it if need be */
int count=0;
for (int j=0; j<length-1; j++)
{
char tempElement[3];
strcpy(tempElement,couples[j]);
int tempCount=0;
for (int p=0; p<length-1; p++)
{
if (couples[p]==tempElement) tempCount++;
}
if (tempCount>count)
{
strcpy(element, tempElement);
count=tempCount;
}
if (tempCount==count)
{
if (isLexicographicallyPreceding(tempElement,element)) strcpy(element, tempElement);
}
}
strcpy(result,element);
}
int main()
{
//Supposed to print "ba" but instead presents "stack smashing detected".
int length=5;
char arr[] = "ababa";
char mostCommonCouple[3]; /* Notice size requirement to also contain the '\0' terminator */
coupleDetector(length,arr,mostCommonCouple);
printf("%s\n", mostCommonCouple);
return 0;
}
Here are some key points.
Viewing the code, most sizes for arrays was enlarged by one to accommodate storage of the null terminator.
Work fields such as "element" need to be defined to their proper size so that subsequent usage won't also result in stack smashing.
Testing out the refactored code resulted in the following terminal output.
#Vera:~/C_Programs/Console/Recurrent/bin/Release$ ./Recurrent
ba
So to reiterate, be cognizant that character arrays normally need to be defined to be large enough to contain the largest expected string plus one for the null terminator.
Give that a try and see if it meets the spirit of your project.
Here's a C source I tried to test:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
main()
{
char c[81];
gets(c);
str_inv(c);
puts(c);
}
void str_inv(char *s[])
{
int i, j;
char *temp;
temp=calloc(1 ,strlen(s)*sizeof(char));
if(temp==NULL)
{
fprintf(stderr, "Error: Memory not allocated.");
exit(1);
}
for(i=0, j=strlen(s)-1; i<strlen(s); i++, j--)
{
temp[i]=s[j];
}
for(i=0; i<strlen(s); i++)
{
s[i]=temp[i];
}
free(temp);
}
An output of the program looks like this:
**abc**
**Process returned 0 (0x0) execution time : 2.262 s**
**Press any key to continue.**
The code in function str_inv works fine while in main() function, but not in separate function.
What is the problem with function?
char *s[] is an array of pointer to char
char s[] is an array of char
Change the function to
void str_inv(char s[])
As a side note. gets() is deprecated, please do not use it. Use fgets() instead.
I need help to understand why in this little program i cannot manipulate correctly pointers:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
void change(char *s[][15]){
int i=0;
while(i<5){
if(s[i][0]=='B') s[i][0]='v';
i++;
}
}
/*My code is supposed to allocate dynamically 5 arrays of 15 chars each
(like tab[5][15])and then put a message on them and try to modify the messages.
In this particular case i'm trying to change the first letter of each string to 'V'.
I'm doing this little experience because of another program
in which i have difficulties accessing double arrays*/
int main(){
int i;
char **s;
s =malloc(5*sizeof(char*));
for(i=0;i<5;i++){
s[i]=malloc(15*sizeof(char));
sprintf(s[i],"Bonjour%d",i);
}
change(s);
for(i=0;i<5;i++){
printf("%s\n",s[i]);
}
return 0;
}
I was expecting :
Vonjour0
Vonjour1
Vonjour2
Vonjour3
Vonjour4
but I get :
Bonjour0
Bonjour1
Bonjour2
Bonjour3
Bonjour4
I'm testing this little code for another program and I don't get why the arrays don't change.
In my other program I can't access the double pointer or print the content.
so my question is : why in this program I can't modify the content of the arrays ?
Your change method needs to use "char** s" instead of char *s[][15]. This is because your method is expecting a pointer to a multi-dimensional array. This is immutable as a result, since your original data type for the string is a pointer to an array of strings (IE: An array of chars).
Hopefully that was clear.
It should be
char **change(char **s){
int i=0;
while(i<5){
if(s[i][0]=='B') s[i][0]='v';
i++;
}
return s;
}
You only need to change the function argument to char *s[].
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
void change(char *s[]){
int i=0;
while(i<5){
if(s[i][0]=='B') s[i][0]='v';
i++;
}
}
int main(){
int i;
char **s;
s =malloc(5*sizeof(char*));
for(i=0;i<5;i++){
s[i]=malloc(15*sizeof(char));
sprintf(s[i],"Bonjour%d",i);
}
change(s);
for(i=0;i<5;i++){
printf("%s\n",s[i]);
}
return 0;
}
Program output:
vonjour0
vonjour1
vonjour2
vonjour3
vonjour4
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
I'm a beginner in C language. After reading the initial chapters of Ritchie's book, I wrote a program to generate random numbers and alphabets.
The program compiles fine with gcc. However on running it, it gives an error "Segmentation fault", which is incomprehensible to my limited knowledge. I'd be glad to understand what I've written wrong.
#include <stdio.h>
#include <stdlib.h>
#include "conio.h"
#include <time.h>
long int genrandom(int,int);
void randAlph(void);
char letterize(int);
int main (void) {
// char full[9];
// char part_non[4];
srand(time(0));
int i;
for (i=0;i<50;++i) {
randAlph();
};
}
long int genrandom(int mino,int maxo) {
int val=mino+rand()/(RAND_MAX/(maxo-mino)+1);
return val;
}
void randAlph (){
int val;
char text;
val=genrandom(0,26);
// return val;
text=letterize(val);
printf("%s ,",text);
}
char letterize(int num) {
char letter='A'+num;
return letter;
}
printf("%s ,",text); is wrong - it says that text is a nul-terminated array of chars. Use
printf("%c ,", text);
instead to print your single char.
#include <stdio.h>
#include <stdlib.h>
#include "conio.h"
#include <time.h>
int genrandom(int,int);
void randAlph(void);
char letterize(int);
int main (void) {
// char full[9];
// char part_non[4];
srand(time(0));
int i;
for (i=0;i<50;++i) {
randAlph();
};
}
int genrandom(int mino,int maxo) {//changed function return type to int
int val=mino+rand()/(RAND_MAX/(maxo-mino)+1); //Be careful when you are using '/' operator with integers
return val; //returning int here why set return type to long int?
}
void randAlph (){
int val;
char text;
val=genrandom(0,26);
// return val;
text=letterize(val);
printf("%c ,",text);//Replace %s with %c
}
char letterize(int num) { //No bound checking on num eh?
char letter='A'+num;
return letter;
}
That's all I had to say. :)
Why use %s when text is char. You dont need a string type in the function. Just a char would do. Change in the function : void randAlph ()
printf("%s ,",text);
to
printf("%c ,", text);