- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
我必须编写一个程序,通过移动句子来输入要加密的句子。我必须先将句子转移到2D数组,其大小必须是一个完美的正方形,以最大化所需的空间。 (例如,如果句子中的字符数为54,则数组的大小将为8,而不是7,因为它适合整个句子)。句子中的空格和空值应替换为下划线。然后我需要该数组向左移动,但是它崩溃了。
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <math.h>
void printArray (int size, char block [size][size])
{
int row, col;
for (row = 0; row < size; row++)
{
printf("\n");
for (col = 0; col < size; col++)
{
printf("%c", block[row][col]);
}
}
}
int main ()
{
// Sentence is "Patience is a minor form of despair disguised as a virtue."
char sentence [1000];
printf("Please enter a sentence to be encrypted: ");
gets (sentence);
int numOfChar = strlen(sentence);
int size = 1;
while (size <= (numOfChar/size))
{
size++;
}
printf("\nThe number of chars is %d and the size is %d", numOfChar, size);
int n = (size * size) - numOfChar; // fills the
empty values with "_"'s
char fillBlank [n];
int i;
for (i = 0; i < n; i++)
{
fillBlank[i] = '_';
}
strcat(sentence, fillBlank);
// ------------------------------------------------ Makes the array ------------------------------------------- //
char block [size][size];
int row;
int col;
int counter = 0;
while (counter < (size * size))
{
for (row = 0; row < size; row++)
{
for (col = 0; col < size; col++)
{
if (sentence [counter] == ' ')
block [row][col] = '_';
else if (sentence[counter] == '\0')
block [row][col] = '_';
else
block [row][col] = sentence [counter];
counter++;
}
}
}
// ------------------------------------------- Prints the array --------------------------------------------- //
printArray(size, block [size][size]);
/*
for (row = 0; row < size; row++)
{
printf("\n");
for (col = 0; col < size; col++)
{
printf("%c", block[row][col]);
}
}
*/
// ------------------------------------------- Shifts the array left --------------------------------------- //
printf("\n\n\n");
char temp [size];
col = 0;
for (row = 0; row < size; row++)
{
temp [row] = block [row][col];
}
for (row = 0; row < size; row++)
{
for (col = 0; col < size; col++)
{
block [row][col] = block [row][col+1];
}
}
col = 7;
for (row = 0; row < size; row++)
{
block [row][col] = temp [row];
}
printArray(size, block [size][size]);
/*
for (row = 0; row < size; row++)
{
printf("\n");
for (col = 0; col < size; col++)
{
printf("%c", block[row][col]);
}
}
*/
return 0;
}
最佳答案
首先,您需要学习计数,句子中包含58-characters
,其次,您使自己变得比原本要难得多。
如果我理解您的问题,您想:
阅读用户输入的句子;
确定长度;
修改句子并将所有spaces
替换为'_'
(下划线);
形成一个最小大小足以容纳句子中字符的正方形数组(例如58个字符,需要8x8数组);
用修改后的句子填充正方形数组,并在句子的最后一个字符之后用下划线填充该数组的所有空白元素;和
将数组中的每一行向左移动1个字符,将第一个字符移到先前由最后一个字符占据的位置。
您已经包含了提供memset
memcpy
和memmove
的必要标头-这将大大简化您的任务。
首先,如注释中所述,永远不要使用gets
。它是如此不安全并且容易被缓冲区溢出利用,因此已从C11标准库中完全删除。请改用fgets
,例如:
#define MAXS 1024 /* if you need a constant - define one (or more) */
...
char sentence [MAXS] = "";
size_t i, len = 0, size;
fputs ("Please enter a sentence to be encrypted:\n", stdout);
if (!fgets (sentence, MAXS, stdin)) { /* read/validate sentence */
fputs ("error: user canceled input or EOF\n", stderr);
return 1;
}
fgets
时,它将最多读取(包括)用户按Enter生成的尾随换行符(
'\n'
)。您需要从句子中删除结尾的
'\n'
。您可以通过在
length - 1
处简单检查字符来完成此操作。如果它是
'\n'
,则只需用nul字符(
'\0'
或等效的
0
)覆盖它。
'\n'
,则需要检查字符串(
-1
)的长度是否是字符串可以容纳的最大长度。如果您已存储了最大数量的字符,而最后一个字符不是
'\n'
-则表明用户输入的字符超出了缓冲区可容纳的字符数–意味着
stdin
中的某些字符尚未读取- -相应地处理,例如
len = strlen (sentence); /* get sentence length */
if (len && sentence[len - 1] == '\n') /* is last char '\n' ? */
sentence[--len] = 0; /* overwrite with nul-char */
else if (len == MAXS - 1) { /* otherwise - input exceeds MAXS chars */
fprintf (stderr, "error: string exceeds %d chars.\n", MAXS);
return 1;
}
len
)确定所需的方阵大小?长度(作为整数值)+1的平方根非常简单:
size = (size_t)sqrt(len); /* set size (trucation intentional) */
if (len % size)
size += 1;
spaces
替换为
'_'
,例如
for (i = 0; i < len; i++) /* replace ' ' with '_' */
if (sentence[i] == ' ')
sentence[i] = '_';
block
声明为2D VLA(如果没有VLA扩展名,则可以声明一个指向char的指针,并分配
size
个指针,并分配一个使用
size
将
malloc
字符分配给每个指针。由于您的原始代码使用的是VLA,因此我们将继续使用。
memset
之前对所有
'_'
数组
memcpy
,例如:
char block[size][size]; /* declare VLA */
memset (block, '_', size * size); /* set all to '_' */
memcpy (block, sentence, len); /* copy sentence to block */
memmove
将行中的每个字符左移1,然后将行中的最后一个字符设置为您保存的临时字符来实现。 (您应该使用
memmove
而不是
memcpy
,因为源和目标内存重叠),例如
/* shift the array left */
for (i = 0; i < size; i++) {
char tmp = *block[i]; /* save 1st char in row */
memmove (block[i], &block[i][1], size - 1); /* shift row left by 1 */
block[i][size - 1] = tmp; /* put 1st char as last */
}
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <math.h>
#define MAXS 1024 /* if you need a constant - define one (or more) */
void printarray (int size, char block [size][size])
{
int row, col;
for (row = 0; row < size; row++) {
for (col = 0; col < size; col++)
putchar (block[row][col]); /* don't use printf to output */
putchar ('\n'); /* a single-character */
}
}
int main (void) {
/* sentence is:
* "Patience is a minor form of despair disguised as a virtue."
*/
char sentence [MAXS] = "";
size_t i, len = 0, size;
fputs ("Please enter a sentence to be encrypted:\n", stdout);
if (!fgets (sentence, MAXS, stdin)) { /* read/validate sentence */
fputs ("error: user canceled input or EOF\n", stderr);
return 1;
}
len = strlen (sentence); /* get sentence length */
if (len && sentence[len - 1] == '\n') /* is last char '\n' ? */
sentence[--len] = 0; /* overwrite with nul-char */
else if (len == MAXS - 1) { /* otherwise - input exceeds MAXS chars */
fprintf (stderr, "error: string exceeds %d chars.\n", MAXS);
return 1;
}
printf ("\nsentence: '%s'\n\n", sentence); /* output sentence */
size = (size_t)sqrt(len); /* set size (trucation intentional) */
if (len % size)
size += 1;
printf("The number of chars is %zu and the size is %zu\n\n", len, size);
for (i = 0; i < len; i++) /* replace ' ' with '_' */
if (sentence[i] == ' ')
sentence[i] = '_';
char block[size][size]; /* declare VLA */
memset (block, '_', size * size); /* set all to '_' */
memcpy (block, sentence, len); /* copy sentence to block */
printf ("block array:\n\n"); /* output original block array */
printarray (size, block);
/* shift the array left */
for (i = 0; i < size; i++) {
char tmp = *block[i]; /* save 1st char in row */
memmove (block[i], &block[i][1], size - 1); /* shift row left by 1 */
block[i][size - 1] = tmp; /* put 1st char as last */
}
printf ("\n\nshifted block array:\n\n");
printarray (size, block);
return 0;
}
%zu
替换所有
%lu
格式说明符,因为Windows不会为
z
提供
size_t
修饰符)
$ ./bin/array_block_shift
Please enter a sentence to be encrypted:
Patience is a minor form of despair disguised as a virtue.
sentence: 'Patience is a minor form of despair disguised as a virtue.'
The number of chars is 58 and the size is 8
block array:
Patience
_is_a_mi
nor_form
_of_desp
air_disg
uised_as
_a_virtu
e.______
shifted block array:
atienceP
is_a_mi_
or_formn
of_desp_
ir_disga
ised_asu
a_virtu_
.______e
memxxx
功能等效项
memxxx
函数的评论和问题以及您正在自学,您可能会受益于仅使用简单循环而不是
memset
,
memcpy
和< cc>。尽管使用久经考验的真正的库函数总能带来更好的收益,但是剥开封面并查看其内部功能有很大的学习价值。
memmove
和
memcpy
实际上可以做同样的事情,但是
memmove
仅在副本的
memcpy
和
source
不重叠的地方定义。
destination
对于确实重叠的区域是安全的。因此,在您的情况下,由于区域重叠,因此我们需要将元素
memmove
留给
1, 2, 3 ... 8
复制到
0, 1, 2 ... 7
处,因此需要使用
memmove
。
man pages
-Wall -Wextra
(并且还应该添加
-pedantic
来添加一些其他警告)。我还建议
-Wshadow
捕获可能导致问题的任何意外阴影变量。
cl.exe
)的Windows上,则至少使用
/W3
(您可以使用
/wdXXXX
禁用Windows上的特定警告,其中
XXXX
是要禁用的警告代码)
/Wall
,则会得到许多与编译器相关的常规警告,这些警告不是针对代码的警告,其中有1/2打
/wdxxxx
会提供有关每个C库函数的详细用法信息。使用它们。只需打开终端,然后输入例如
man pages
即可了解
man memmove
功能。学习时(甚至在您认为自己已经学习过某个功能之后),如果对如何使用它或使用合适的参数有疑问,请始终咨询
memmove
,最重要的是,它在成功时会返回什么值以及成功时会返回什么值返回以指示失败(以及是否在
man functionname
中设置了其他信息,可以使用
errno
进行检索-打印错误)。如果您仅合并使用这些可用的基本工具,就可以将学习的挫败感降低十倍,并且比以往任何时候都快几年。
perror()
的所有依赖(这将使您了解为什么它们可以简化您的生活)
#include <stdio.h>
#include <string.h>
#define MAXS 1024 /* if you need a constant - define one (or more) */
void printarray (int size, char block [size][size])
{
int row, col;
for (row = 0; row < size; row++) {
for (col = 0; col < size; col++)
putchar (block[row][col]); /* don't use printf to output */
putchar ('\n'); /* a single-character */
}
}
int main (void) {
/* sentence is:
* "Patience is a minor form of despair disguised as a virtue."
*/
char sentence [MAXS] = "";
size_t i, j, len = 0, size;
fputs ("Please enter a sentence to be encrypted:\n", stdout);
if (!fgets (sentence, MAXS, stdin)) { /* read/validate sentence */
fputs ("error: user canceled input or EOF\n", stderr);
return 1;
}
len = strlen (sentence); /* get sentence length */
if (len && sentence[len - 1] == '\n') /* is last char '\n' ? */
sentence[--len] = 0; /* overwrite with nul-char */
else if (len == MAXS - 1) { /* otherwise - input exceeds MAXS chars */
fprintf (stderr, "error: string exceeds %d chars.\n", MAXS);
return 1;
}
printf ("\nsentence: '%s'\n\n", sentence); /* output sentence */
if (len < 4) {
fputs ("error: sentence less than 4 chars - too short.\n", stderr);
return 1;
}
for (size = 2; size * size < len; size++) {} /* set size */
printf("The number of chars is %zu and the size is %zu\n\n", len, size);
for (i = 0; i < len; i++) /* replace ' ' with '_' */
if (sentence[i] == ' ')
sentence[i] = '_';
char block[size][size]; /* declare VLA */
for (i = 0; i < size; i++) /* initialize all element '_' */
for (j = 0; j < size; j++) /* (memset (block, '_', size) */
block[i][j] = '_';
size_t n = 0;
for (i = 0; i < size; i++) /* copy sentence to block */
for (j = 0; j < size; j++) /* (memcpy (block, sentence, len) */
if (n < len)
block[i][j] = sentence[n++];
else
break;
printf ("block array:\n\n"); /* output original block array */
printarray (size, block);
/* shift the array left (memmove (block[i], &block[i][1], size - 1)) */
for (i = 0; i < size; i++) {
char tmp = block[i][0]; /* save 1st char in row */
for (j = 1; j < size; j++)
block[i][j-1] = block[i][j];
block[i][size - 1] = tmp; /* put 1st char as last */
}
printf ("\n\nshifted block array:\n\n");
printarray (size, block);
return 0;
}
memxxx
的实际作用,可以使用:
for (i = 0; i < len; i++) /* copy sentence to block */
(*block)[i] = sentence[i]; /* (memcpy (block, sentence, len) */
memcpy (block, sentence, len)
小于
len
的2D数组。此外,它不适用于您为
size * size
分配了每个
char **
个字符的
size
指针的情况。为什么?只有一个数组可以保证所有元素在内存中都是顺序的。当使用指针集合和独立分配的内存块来模拟2D数组时,无法保证。
关于c - 为什么我的程序在运行时崩溃,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/50126709/
我是 C 语言新手,我编写了这个 C 程序,让用户输入一年中的某一天,作为返回,程序将输出月份以及该月的哪一天。该程序运行良好,但我现在想简化该程序。我知道我需要一个循环,但我不知道如何去做。这是程序
我一直在努力找出我的代码有什么问题。这个想法是创建一个小的画图程序,并有红色、绿色、蓝色和清除按钮。我有我能想到的一切让它工作,但无法弄清楚代码有什么问题。程序打开,然后立即关闭。 import ja
我想安装screen,但是接下来我应该做什么? $ brew search screen imgur-screenshot screen
我有一个在服务器端工作的 UDP 套接字应用程序。为了测试服务器端,我编写了一个简单的 python 客户端程序,它发送消息“hello world how are you”。服务器随后应接收消息,将
我有一个 shell 脚本,它运行一个 Python 程序来预处理一些数据,然后运行一个 R 程序来执行一些长时间运行的任务。我正在学习使用 Docker 并且我一直在运行 FROM r-base:l
在 Linux 中。我有一个 c 程序,它读取一个 2048 字节的文本文件作为输入。我想从 Python 脚本启动 c 程序。我希望 Python 脚本将文本字符串作为参数传递给 c 程序,而不是将
前言 最近开始整理笔记里的库存草稿,本文是 23 年 5 月创建的了(因为中途转移到 onedrive,可能还不止) 网页调起电脑程序是经常用到的场景,比如百度网盘下载,加入 QQ 群之类的 我
对于一个类,我被要求编写一个 VHDL 程序,该程序接受两个整数输入 A 和 B,并用 A+B 替换 A,用 A-B 替换 B。我编写了以下程序和测试平台。它完成了实现和行为语法检查,但它不会模拟。尽
module Algorithm where import System.Random import Data.Maybe import Data.List type Atom = String ty
我想找到两个以上数字的最小公倍数 求给定N个数的最小公倍数的C++程序 最佳答案 int lcm(int a, int b) { return (a/gcd(a,b))*b; } 对于gcd,请查看
这个程序有错误。谁能解决这个问题? Error is :TempRecord already defines a member called 'this' with the same paramete
当我运行下面的程序时,我在 str1 和 str2 中得到了垃圾值。所以 #include #include #include using namespace std; int main() {
这是我的作业: 一对刚出生的兔子(一公一母)被放在田里。兔子在一个月大时可以交配,因此在第二个月的月底,每对兔子都会生出两对新兔子,然后死去。 注:在第0个月,有0对兔子。第 1 个月,有 1 对兔子
我编写了一个程序,通过对字母使用 switch 命令将十进制字符串转换为十六进制,但是如果我使用 char,该程序无法正常工作!没有 switch 我无法处理 9 以上的数字。我希望你能理解我,因为我
我是 C++ 新手(虽然我有一些 C 语言经验)和 MySQL,我正在尝试制作一个从 MySQL 读取数据库的程序,我一直在关注这个 tutorial但当我尝试“构建”解决方案时出现错误。 (我正在使
仍然是一个初学者,只是尝试使用 swift 中的一些基本函数。 有人能告诉我这段代码有什么问题吗? import UIKit var guessInt: Int var randomNum = arc
我正在用 C++11 编写一个函数,它采用 constant1 + constant2 形式的表达式并将它们折叠起来。 constant1 和 constant2 存储在 std::string 中,
我用 C++ 编写了这段代码,使用运算符重载对 2 个矩阵进行加法和乘法运算。当我执行代码时,它会在第 57 行和第 59 行产生错误,非法结构操作(两行都出现相同的错误)。请解释我的错误。提前致谢:
我是 C++ 的初学者,我想编写一个简单的程序来交换字符串中的两个字符。 例如;我们输入这个字符串:“EXAMPLE”,我们给它交换这两个字符:“E”和“A”,输出应该类似于“AXEMPLA”。 我在
我需要以下代码的帮助: 声明 3 个 double 类型变量,每个代表三角形的三个边中的一个。 提示用户为第一面输入一个值,然后 将用户的输入设置为您创建的代表三角形第一条边的变量。 将最后 2 个步
我是一名优秀的程序员,十分优秀!