我收到一个带字符串的文件,例如"The United States was founded in *1776*"
。我无法弄清楚的是如何将字母向左或向右移动一个空格并让字母环绕。我可以将字母从a移到b但不改变它在单词中的位置。
此输出的示例为:
"heT
nitedU
tatesS
asw
oundedf
ni
1776**"
答案 0 :(得分:1)
在C中,字符串作为字符数组存储在内存中。与C ++向量不同,您不能在数组中插入或删除元素,只能访问它们的值或更改它们的值。
如果您按如下方式声明C字符串:
char *myStr = "Fred";
它将作为五个字符的数组存储在内存中,第5个字符为零值,终止C字符串:
myStr[0] = 'F'
myStr[1] = 'r'
myStr[2] = 'e'
myStr[3] = 'd'
myStr[4] = 0
您需要设计一个for
循环,将每个数组元素复制到之前,同时记住您需要保存要覆盖的数组元素。在此示例中,它应导致执行以下复制操作:
len = strlen(myStr);
saveCh = myStr[0];
myStr[0] = myStr[1];
myStr[1] = myStr[2];
myStr[2] = myStr[3];
myStr[3] = saveCh;
所以现在你的工作是创建一个for
循环,为任何长度的任何C字符串执行此操作。
因此,要将C字符串中的字符向左旋转,您需要将索引i处的数组中的每个字符复制到前一个数组元素i-1。棘手的部分是在i = 0时正确处理环绕(在此示例中,您要将myStr[0]
复制到myStr[3]
。现在使用for
循环执行此操作。
您还需要了解任何C字符串的最后一个字符是空字符(值为零),它终止C字符串。如果您修改数组中的该元素,那么您的字符串将会中断。这就是saveCh
被复制到myStr[3]
而不是myStr[4]
的原因。
void rotateStrLeftOneChar(char *myStr) {
// Always check for error and special cases first!
// If myStr is a NULL pointer, do nothing and exit
// If myStr is less than 2 chars, nothing needs to be done too.
if ((myStr != NULL) && (strlen(myStr)>1)) {
int len = strlen(myStr);
char saveCh = myStr[0];
int i = 0;
// Copy each char at index i+1 left to index i in the array
for(i=0; i<len-2; i++)
myStr[i] = myStr[i+1];
// The last character is special and is set to saveCh
myStr[len-1] = saveCh;
}
}
答案 1 :(得分:1)
如果您只需输出字母向左移动而不想更改原始输入,则可以执行以下操作:
#include <stdio.h>
#include <string.h>
void shiftletters(char * input, int i);
int main () {
char input[256];
int shift;
printf("Enter input : ");
scanf("%[^\n]s", input);
printf("Number of shifts : ");
scanf("%d", &shift);
shiftletters(input, shift);
return 0;
}
void shiftletters(char * input, int numshifts)
{
char str[256] = {'\0'};
char * delim = " \t";
char * pch = NULL;
int j, k, len, shifts;
if (input == NULL)
{
printf ("Invalid input\n");
return;
}
strcpy (str, input);
pch = strtok (str, delim);
while (pch != NULL)
{
len = strlen (pch);
if ((numshifts == len) || (len == 1))
{
printf ("%s\n", pch);
pch = strtok (NULL, delim);
continue;
}
if (len < numshifts)
shifts = numshifts % len;
else
shifts = numshifts;
for(j=shifts; j<len; j++)
printf("%c", pch[j]);
for(k=0; k<shifts; k++)
printf("%c", pch[k]);
printf("\n");
pch = strtok (NULL, delim);
}
}
该计划的输出:
Enter input : The United States was founded in *1776*
Number of shifts : 1
heT
nitedU
tatesS
asw
oundedf
ni
1776**
答案 2 :(得分:0)
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
enum { L = -1, R = 1};
char *rotate(char word[], int dir){
size_t len = strlen(word);
char *temp = malloc(len + 1);
if(!temp){
perror("malloc");
exit(EXIT_FAILURE);
}
strcpy(temp, word);
for(char *src = temp; *src; ++src, ++dir){//or use memmove
word[(dir+len)%len] = *src;
}
free(temp);
return word;
}
int main(int argc, char *argv[]) {
FILE *fp = fopen("data.txt", "r");
if(fp == NULL){
perror("fopen");
exit(EXIT_FAILURE);
}
if(argc < 2){
fprintf(stderr, "Usage %s L|R...\n", argv[0]);
exit(EXIT_FAILURE);
}
char word[64];
while(fscanf(fp, "%63s", word)==1){
for(char *shift = argv[1]; *shift; ++shift){
int dir = *shift == 'L' ? L : R;
rotate(word, dir);
}
printf("%s\n", word);
}
fclose(fp);
}
使用memmove版本
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
enum { L = -1, R = 1};
char *rotate1(char word[], int dir){
size_t len = strlen(word);
if(len > 2){
char temp;
if(dir == L){
temp = word[0];
memmove(word, word+1, len-1);
word[len-1] = temp;
} else if(dir == R){
temp = word[len-1];
memmove(word+1, word, len-1);
word[0] = temp;
}
}
return word;
}
int main(int argc, char *argv[]) {
FILE *fp = fopen("data.txt", "r");
if(fp == NULL){
perror("fopen");
exit(EXIT_FAILURE);
}
if(argc < 2){
fprintf(stderr, "Usage %s L|R...\n", argv[0]);
exit(EXIT_FAILURE);
}
char word[64];
while(fscanf(fp, "%63s", word)==1){
for(char *shift = argv[1]; *shift; ++shift){
int dir = *shift == 'L' ? L : R;
rotate1(word, dir);
}
printf("%s\n", word);
}
}