I'm trying to implement a sorting function which would sort the characters from an array. Can someone tell why it's not working?
int main()
{
char tab[] = {'e', 'b', 'd', 'z', 'a', 't', '\0'};
char tab2[7] = {0};
int i = 0, j = 0, k = 0;
while (tab[i] != '\0')
{
for (j = 0; tab[j] != '\0'; j++)
{
if (tab[i] > tab2[j])
{
tab2[k] = tab[j];
k++;
}
}
k=0;
i++;
}
printf("%s\n", tab2);
return 0;
}
You '\0' has value 0 while your letters have value of 97+ for lower cases letter, so once your array is sorted the '\0' is at the very beginning.
use man ascii in the terminal or check the wikipedia link.
You can initialize your final array values at 127 and then sort the following way:
#include <stdio.h>
void swap(char *x, char *y)
{
if (x != y)
{
*x ^= *y;
*y ^= *x;
*x ^= *y;
}
}
int main()
{
char tab[] = {'e', 'b', 'd', 'z', 'a', 't', '\0'};
char tab2[7];
for (int l = 0; l < 6; l++)
tab2[l] = 127;
tab2[6] = 0;
int i = 0, j = 0;
while (tab[i] != '\0')
{
for (j = 0; tab[j] != '\0'; j++)
{
if (tab[i] < tab2[j]) // this is bubble sort, check if value is inferior
swap(&tab[i], &tab2[j]); // if it is then swap pointers
}
i++;
}
printf("%s\n", tab2);
return 0;
}
output:
abdetz
Related
#include <stdio.h>
#include <stdlib.h>
#include <ctype.h>
#include <string.h>
void encryptmessage1(char[][6]);
void encryptmessage2(char[][6]);
int
main()
{
char array[5][6] = {
{'A', 'B', 'C', 'D', 'E'},
{'F', 'G', 'H', 'I', 'J'},
{'K', 'L', 'M', 'N', 'O'},
{'P', 'Q', 'Z', 'R', 'S', 'T'},
{'U', 'V', 'W', 'X', 'Y'}
};
int choice;
printf("********************************\n");
printf("**ENCRYPTION/DECRYPTION SYSTEM**\n");
printf("********************************\n");
printf("\n");
printf("1.Code the message\n");
printf("2.Decode the message\n");
printf("3.EXIT\n");
printf("Make your choice: ");
scanf("%d", &choice);
switch (choice) {
case 1:
encryptmessage1(array);
encryptmessage2(array);
break;
case 2:
// decrypt message
break;
default:
break;
}
return 0;
}
void
encryptmessage1(char array[][6])
{
int i, j, loop, k = 0, row, col, len = 0;
char str[80] = {};
char temparr[80] = {}; // temporary array
char temp;
printf("Please enter your message : ");
temp = getchar();
// reads string
while ((str[k] = getchar()) != '\n') {
k++;
}
i = 0;
// loop to temporary store values from another array
for (loop = 0; loop < 80; loop++) {
temparr[loop] = str[loop];
}
// Calculating length of the array
len = sizeof(str) / sizeof(str[0]);
// Checks for space character in array if its there then ignores it
// and swap str[i] to str[i+1];
for (i = 0; i < len; i++) {
if (str[i] == ' ') {
for (j = i; j < len; j++) {
str[j] = str[j + 1];
}
len--;
}
}
i = 0;
// from lowercase to uppercase
while (str[i] != '\n') {
if (islower(str[i])) {
str[i] = toupper(str[i]);
}
i++;
}
puts(str);
i = 0;
k = 0;
while (str[k] != '\n') {
for (row = 0; row < 5; row++) {
for (col = 0; col < 6; col++) {
if (str[k] == array[row][col]) {
temparr[i] = '0' + row;
temparr[i + 1] = '0' + col;
i += 2;
}
}
}
k++;
}
puts(temparr);
}
void
encryptmessage2(char array[][6])
{ int i, j, loop, k =0, row, col;
char key[80] = {};
char temparr2[80] = {}; // temporary array
char temp;
printf("Please enter your key : ");
temp = getchar();
// reads string
while ((key[k] = getchar()) != '\n') {
k++;
}
i = 0;
// loop to temporary store values from another array
for (loop = 0; loop < 80; loop++) {
temparr2[loop] = key[loop];
}
// array from lowercase to uppercase
while (key[i] != '\n') {
if (islower(key[i])) {
key[i] = toupper(key[i]);
}
i++;
}
//Printing the array with spaces using pointer
char *ptr = key;
if (*ptr) {
putchar(*ptr++);
while (*ptr) {
putchar(' ');
putchar(*ptr++);
}
}
}
[outputoftheproblem](https://i.stack.imgur.com/wLUGa.png)
If I type in the keyword cortina it just prints out ortina without the first letter
I dont know if the problem is with the pointer
Also any ideas how can I print out the same set of numbers which were encrypted from str[] as an array under the 'CORTINA' word like the example above:
C O R T I N A
1 1 0 0 3 4 0
3 4 5 6 3 2 5
2 3 4 5 6 7 8
2 3 4 3 2 4 5
I fixed the missing first character and out of bounds access. Refactored code reduce duplication and minimize scope of variables.
The key is printing as requested but it's not clear how you want to align the key and cipher text. You are printing ciphertext before the key is read, and you are not using the key for anything in your code. I assume you want to scramble the array using the key.
#include <stdio.h>
#include <stdlib.h>
#include <ctype.h>
#include <string.h>
#define STR_LEN 80
void encode(const char array[][6], const char *plaintext, char *ciphertext);
void encrypt(const char array[][6]);
int lookup(const char array[][6], char c, size_t *row, size_t *col);
void strip(char *str);
void upcase(char *str);
void encode(const char array[][6], const char *plaintext, char *ciphertext) {
size_t i = 0;
for(; plaintext[i]; i++) {
size_t row;
size_t col;
if(lookup(array, plaintext[i], &row, &col)) {
ciphertext[2 * i] = '0' + row;
ciphertext[2 * i + 1] = '0' + col;
} else {
ciphertext[2 * i] = ' ';
ciphertext[2 * i + 1] = ' ';
}
}
ciphertext[2*i] = '\0';
puts(ciphertext);
}
void encrypt(const char array[][6]) {
printf("Please enter your message : ");
char plaintext[STR_LEN];
fgets(plaintext, sizeof plaintext, stdin);
plaintext[strcspn(plaintext, "\n")] = '\0';
strip(plaintext);
upcase(plaintext);
puts(plaintext);
char ciphertext[2 * STR_LEN - 1];
encode(array, plaintext, ciphertext);
printf("Please enter your key : ");
char key[STR_LEN];
fgets(key, sizeof key, stdin);
key[strcspn(key, "\n")] = '\0';
upcase(key);
for(size_t i = 0; key[i]; i++) {
putchar(key[i]);
putchar(' ');
}
putchar('\n');
}
int lookup(const char array[][6], char c, size_t *row, size_t *col) {
for(*row = 0; *row < 5; (*row)++)
for(*col = 0; *col < 6; (*col)++)
if(c == array[*row][*col])
return 1;
return 0;
}
void strip(char *str) {
size_t i = 0;
for(size_t j = 0; str[j];) {
if(str[j] == ' ')
j++;
else
str[i++] = str[j++];
}
str[i] = '\0';
}
void upcase(char *str) {
while(*str) {
*str = toupper(*str);
str++;
}
}
int main(void ) {
printf(
"********************************\n"
"**ENCRYPTION/DECRYPTION SYSTEM**\n"
"********************************\n"
"1. Code the message\n"
"2. Decode the message\n"
"3. EXIT\n"
"Make your choice: "
);
char choice[3];
fgets(choice, 3, stdin);
if(*choice == '1') {
const char array[5][6] = {
{'A', 'B', 'C', 'D', 'E'},
{'F', 'G', 'H', 'I', 'J'},
{'K', 'L', 'M', 'N', 'O'},
{'P', 'Q', 'Z', 'R', 'S', 'T'},
{'U', 'V', 'W', 'X', 'Y'}
};
encrypt(array);
}
}
Here is the sample run:
********************************
**ENCRYPTION/DECRYPTION SYSTEM**
********************************
1. Code the message
2. Decode the message
3. EXIT
Make your choice: 1
Please enter your message : test
TEST
35043435
Please enter your key : cortina
C O R T I N A
I'm currently in the middle of one of my coding assignments, in which We create a gameboard for a game of reversi (Othello), give it some initial condition, and check for legality of moves.
The code begins by asking the user for the size of the board (sidelength) and uses one function to initialize the board and another to print it.
My code works fine for boardDim = 4 and boardDim = 6, however when I enter 8, after the function responsible for initializing the board executes all its statements, the value of boardDim jumps to something like 21568 and that leads to a segmentation error Note: lab handout says we can assume that sidelength of board will never exceed 26
Thanks for reading!
Here is my code:
void InitBoard(char reversiBoard[][26], const int a) {
for (int i = 0; i < a; i++) {
for (int j = 0; j < a; j++) {
if ((i == (a / 2 - 1)) && (j == (a / 2 - 1))) {
reversiBoard[i][j] = 'W';
}
else if ((i == (a / 2 - 1)) && (j == a / 2)) {
reversiBoard[i][j] = 'B';
}
else if ((i == a / 2) && (j == (a / 2 - 1))) {
reversiBoard[i][j] = 'B';
}
else if ((i == a / 2) && (j == a / 2)) {
reversiBoard[i][j] = 'W';
}
else {
reversiBoard[i][j] = 'U';
}
}
}
return;
}
void printBoardCurr(char reversiBoard[][26], const int a) {
char alphabet[] = { 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z' };
printf(" ");
for (int i = 0; i < a; i++) {
printf("%c", (alphabet[i]));
}
printf("\n\n");
for (int j = 0; j < a; j++) {
printf("%c ", (alphabet[j]));
for (int k = 0; k < a; k++) {
printf("%c", reversiBoard[j][k]);
}
printf("\n");
}
return;
}
int main(void) {
int boardDim = 0;
printf("Enter the board dimension: ");
scanf(" %d", &boardDim);
char reversiBoard[boardDim][boardDim];
InitBoard(reversiBoard, boardDim);
printBoardCurr(reversiBoard, boardDim);
return 0;
}
I need some help with my code. The question is:
Write a function void printSquare(char c, int size)
that accepts a letter of the alphabet and a number between 3 and 10 and
generates the following rectangle of letters:
If the letter passed is a and the size is 4:
abcd
bcde
cdef
defg
If the letter is W and the size is 6, the output should be
WXYZAB
XYZABC
YZABCD
ZABCDE
ABCDEF
BCDEFG
I have been trying to debug this for a long time and cannot get anywhere and need help. This is what the code looks like right now:
void printSquare(char c, int size);
int main() {
printSquare('b', 4);
system("pause");
return 0;
}
void printSquare(char c, int size){
int counter = 0;
char letters[26] = { 'a', 'b', 'c', 'd',
'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n',
'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z' };
for (int i = 0; i < 26; i++){
if (c == letters[i]){
int temp = i;
for (int j = 0; j < size; j++){
letters[i] = letters[temp];
temp++;
for (int k = 0; k < size; k++){
printf("%c", letters[i]);
letters[i++];
}
printf("\n");
}
}
}
}
Assuming encoding where capital and small letters are sequential (e.g. ASCII), you may consider something like this:
void printSquare(char c, int size)
{
char a = ('A' <= c && c <= 'Z') ? 'A' : 'a';
for (int i = 0; i < size; ++i)
{
for (int j = 0; j < size; ++j)
// (c - a) is the offset of c from 'A' or 'a'
// i defines an extra offset for every line, so lines start with c, c+1, ...
// j defines an offset for a character within line
// % 26 makes sure that overall offset does not go beyond the alphabet length
printf("%c", a + (c - a + i + j) % 26);
printf("\n");
}
}
void printSquare(char c, int size){
if(isalpha(c) && 3 <= size && size <= 10){
const char *table = isupper(c) ?
"ABCDEFGHIJKLMNOPQRSTUVWXYZABCDEFGHIJKLMNOPQRSTUVWXYZ" :
"abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyz" ;
char *p = strchr(table, c);
for(int i = 0; i < size; ++i){
fwrite(p++, 1, size, stdout);
puts("");
}
}
}
I want to return part (or let's say substring) of a char* in C. The point is that user defines the starting index and the length that I want to return. First of all, I check whether the given values are in the range and positive, if they are not, I want to return a null.
Here is what I have tried:
#include <stdio.h>
#include <stdlib.h>
char * f(char a[], int start, int len, int lenA)
{
int i, j = 1;
char *temp;
if ((start + len) > lenA)
return NULL;
if (start < 0 || len < 0)
return NULL;
else if (len == 0) {
temp = malloc(sizeof(char)*1);
return temp;
}
temp = malloc(sizeof(char)*len);
for (i = 0; len >= j; i++, j++) {
temp[i] = a[start];
start++;
}
return temp;
}
int main(void)
{
int i;
char *a = {'a', 'b', 'c'};
a = f(a, 0, 2, 3);
int size = sizeof(a) / sizeof(a[0]);
if (a != NULL) {
printf("{");
for (i = 0; i < size; i++) {
printf("'%c',", a[i]);
if (i < (size - 1))
printf(" ");
}
printf("}\n");
}
else printf("null\n");
return 0;
}
The point is that when I when I run it, I get an error message saying: Segmentation fault (core dumped)
Instead, it should print this: {'a', 'b'}. While as you can see in my main, I called the function with 0 start index, and length of two, so it should get the first two characters. Any idea, how to fix it?
char *a = {'a', 'b', 'c'};
is not valid C code. Please enable your compiler warnings.
If you want an array of char use:
char a[] = {'a', 'b', 'c'};
or for a null terminated string:
char a[] = "abc";
This is working for me on VS Express 2013. I didn't go through all your code. But I seem to have fixed the problem. int size = sizeof(a) / sizeof(a[0]); - this shouldn't work. You're dividing the size of a pointer (4 bytes) by the size of a character (1 byte).
#include <stdio.h>
#include <stdlib.h>
char * f(char a[], int start, int len, int lenA)
{
int i, j = 1;
char *temp;
if ((start + len) > lenA)
return NULL;
if (start < 0 || len < 0)
return NULL;
else if (len == 0) {
temp = malloc(sizeof(char)* 1);
return temp;
}
temp = malloc(sizeof(char)*len);
for (i = 0; len >= j; i++, j++) {
temp[i] = a[start];
start++;
}
return temp;
}
int main(void)
{
int i;
char arr[] = { 'a', 'b', 'c' }; //code changed here
char *a = f(arr, 0, 2, 3); //code changed here
int size = 2; //code changed here - consider using the same variable for the length above and size here
if (a != NULL) {
printf("{");
for (i = 0; i < size; i++) {
printf("%c,", a[i]);
if (i < (size - 1))
printf(" ");
}
printf("}\n");
}
else printf("null\n");
system("PAUSE");
return 0;
}
Let me know if you need any more help. I didn't test this for all cases. Also, don't forget to free the memory you are allocating dynamically.
#include "usefunc.h"
#define MY_SIZE 256
int inpArr(char tmp[], int size) {
size = -1;
while(1) {
size++;
if((tmp[size] = getchar()) == '\n') break;
}
return size;
}
void revString(char tmp[], int size, char new[]) {
int i, j;
for (i = size, j = 0; i >= 0; i--, j++) new[j] = tmp[i];
}
void copy_forw(char tmp[], int size, char new[], int offset) {
int i, j;
for (i = offset, j = 0; i <= size; i++, j++) new[j] = tmp[i];
}
void copy_back(char tmp[], int size, char new[], int offset) {
int i, j;
for (i = size-offset, j = size; i > -1; i--, j--) new[j] = tmp[i];
}
void cut(char tmp[], int size, char new[]) {
}
int main () {
char tmp[MY_SIZE] = {0x0}, rev[MY_SIZE] = {0x0}, new[MY_SIZE] = {0x0}, some[MY_SIZE-1];
int size = inpArr(tmp, size);
revString(tmp, size, rev);
copy_forw(rev, size, new, 1); copy_back(tmp, size, some, 1);
printf("|%s|\n|%s|\n", some, new);
int is_palindrome = StringEqual(new, some);
printf("%d\n", is_palindrome);
}
StringEqual is pretty much a function that just compares a char array character by character.
If I input the string yay it should be a palindrome, but doesn't appear to be. Why is this?
Your problem is with the line that goes:
if((tmp[size] = getchar()) == '\n') break;
This line will always assign the character the user inputs into the array, even when the user inputs the \n character to indicate that they are done providing input. So for example, when you enter "yay" and then a newline to indicate that you are done, your array looks like:
{'y', 'a', 'y', '\n'}
and the reverse of that array is:
{'\n', 'y', 'a', 'y'}
...which will obviously fail a palindrome check. I would suggest revising your code as follows:
int inpArr(char tmp[], int size) {
size = -1;
while(1) {
size++;
if((tmp[size] = getchar()) == '\n') break;
}
tmp[size] = '\0'; //replace the newline with a null terminator
return size;
}
void revString(char tmp[], int size, char new[]) {
int i, j;
for (i = size - 1, j = 0; i >= 0; i--, j++) new[j] = tmp[i];
new[size] = '\0'; //place a null terminator at the end of the reversed string
}
Look at line:
if((tmp[size] = getchar()) == '\n') break;
'\n' is always present at the end of the string. That's your problem.